diff options
author | Werner Koch <[email protected]> | 2000-01-14 17:26:00 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2000-01-14 17:26:00 +0000 |
commit | 932049cbe4282b3077a5f903838d86137c727e6b (patch) | |
tree | 2bc3de4afdea415fcb53119cad7616b168bc78f7 | |
parent | See ChangeLog: Thu Jan 13 19:31:58 CET 2000 Werner Koch (diff) | |
download | gnupg-932049cbe4282b3077a5f903838d86137c727e6b.tar.gz gnupg-932049cbe4282b3077a5f903838d86137c727e6b.zip |
See ChangeLog: Fri Jan 14 18:32:01 CET 2000 Werner Koch
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | NEWS | 10 | ||||
-rw-r--r-- | cipher/ChangeLog | 14 | ||||
-rw-r--r-- | cipher/blowfish.c | 12 | ||||
-rw-r--r-- | cipher/cast5.c | 13 | ||||
-rw-r--r-- | cipher/des.c | 13 | ||||
-rw-r--r-- | cipher/md5.c | 8 | ||||
-rw-r--r-- | cipher/rmd160.c | 8 | ||||
-rw-r--r-- | cipher/sha1.c | 4 | ||||
-rw-r--r-- | cipher/tiger.c | 8 | ||||
-rw-r--r-- | cipher/twofish.c | 27 | ||||
-rw-r--r-- | doc/DETAILS | 9 | ||||
-rw-r--r-- | doc/FAQ | 27 | ||||
-rw-r--r-- | doc/OpenPGP | 9 | ||||
-rw-r--r-- | doc/gpg.sgml | 10 | ||||
-rw-r--r-- | g10/ChangeLog | 11 | ||||
-rw-r--r-- | g10/build-packet.c | 19 | ||||
-rw-r--r-- | g10/export.c | 31 | ||||
-rw-r--r-- | g10/g10.c | 11 | ||||
-rw-r--r-- | g10/keyedit.c | 26 | ||||
-rw-r--r-- | g10/main.h | 1 | ||||
-rw-r--r-- | g10/packet.h | 2 | ||||
-rw-r--r-- | g10/parse-packet.c | 35 | ||||
-rw-r--r-- | g10/seckey-cert.c | 4 | ||||
-rw-r--r-- | mpi/ChangeLog | 2 |
25 files changed, 250 insertions, 66 deletions
@@ -1,6 +1,6 @@ Thu Jan 13 19:31:58 CET 2000 Werner Koch <[email protected]> - * configure.in: Do set development version when the version has + * configure.in: Do not set development version when the version has a dash in it. Suggested by Dave Dykstra. Thu Dec 16 10:07:58 CET 1999 Werner Koch <[email protected]> @@ -1,3 +1,5 @@ +Noteworthy changes in the current test release +---------------------------------------------- * Some fixes for the W32 version @@ -7,6 +9,14 @@ * New encryption keys are generated in way which allows a much faster decryption. + * New command --export-secret-subkeys which outputs the + the _primary_ key with is's secret parts deleted. This is + useful for automated decryption/signature creation as it + allows to keep the real secret primary key offline and + thereby protecting the key certificates and allowing to + create revocations for the subkeys. See the FAQ for a + procedure to install such secret keys. + Noteworthy changes in version 1.0.1 (1999-12-16) ----------------------------------- diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 2a53aff1a..6804a7b19 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,15 @@ +Fri Jan 14 18:32:01 CET 2000 Werner Koch <[email protected]> + + * rmd160.c (rmd160_get_info): Moved casting to the left side due to a + problem with UTS4.3. Suggested by Dave Dykstra. + * sha1.c (sha1_get_info): Ditto. + * tiger.c (tiger_get_info): Ditto. + * md5.c (md5_get_info): Ditto + * des.c (des_get_info): Ditto. + * blowfish.c (blowfish_get_info): Ditto. + * cast5.c (cast5_get_info): Ditto. + * twofish.c (twofish_get_info): Ditto. + Thu Jan 13 19:31:58 CET 2000 Werner Koch <[email protected]> * elgamal.c (wiener_map): New. @@ -5,7 +17,7 @@ Thu Jan 13 19:31:58 CET 2000 Werner Koch <[email protected]> (generate): Calculate the qbits using the wiener map and choose an x at a size comparable to the one choosen in gen_k - * random.c (read_pool): Print a more friendly erro message in + * random.c (read_pool): Print a more friendly error message in cases when too much random is requested in one call. * Makefile.am (tiger): Replaced -O1 by -O. Suggested by Alec Habig. diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 5a829d413..0cb5a861f 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -43,9 +43,6 @@ #define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */ -#define FNCCAST_SETKEY(f) (int(*)(void*, byte*, unsigned))(f) -#define FNCCAST_CRYPT(f) (void(*)(void*, byte*, byte*))(f) - #define BLOWFISH_BLOCKSIZE 8 #define BLOWFISH_ROUNDS 16 @@ -584,9 +581,12 @@ blowfish_get_info( int algo, size_t *keylen, *keylen = 128; *blocksize = BLOWFISH_BLOCKSIZE; *contextsize = sizeof(BLOWFISH_context); - *r_setkey = FNCCAST_SETKEY(bf_setkey); - *r_encrypt= FNCCAST_CRYPT(encrypt_block); - *r_decrypt= FNCCAST_CRYPT(decrypt_block); + *(int (**)(BLOWFISH_context*, byte*, unsigned))r_setkey + = bf_setkey; + *(void (**)(BLOWFISH_context*, byte*, byte*))r_encrypt + = encrypt_block; + *(void (**)(BLOWFISH_context*, byte*, byte*))r_decrypt + = decrypt_block; if( algo == CIPHER_ALGO_BLOWFISH ) return "BLOWFISH"; diff --git a/cipher/cast5.c b/cipher/cast5.c index 0e602bd2e..329f00ff7 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -46,9 +46,6 @@ #define CIPHER_ALGO_CAST5 3 -#define FNCCAST_SETKEY(f) (int(*)(void*, byte*, unsigned))(f) -#define FNCCAST_CRYPT(f) (void(*)(void*, byte*, byte*))(f) - #define CAST5_BLOCKSIZE 8 typedef struct { @@ -610,9 +607,13 @@ cast5_get_info( int algo, size_t *keylen, *keylen = 128; *blocksize = CAST5_BLOCKSIZE; *contextsize = sizeof(CAST5_context); - *r_setkey = FNCCAST_SETKEY(cast_setkey); - *r_encrypt= FNCCAST_CRYPT(encrypt_block); - *r_decrypt= FNCCAST_CRYPT(decrypt_block); + *(int (**)(CAST5_context*, byte*, unsigned))r_setkey + = cast_setkey; + *(void (**)(CAST5_context*, byte*, byte*))r_encrypt + = encrypt_block; + *(void (**)(CAST5_context*, byte*, byte*))r_decrypt + = decrypt_block; + if( algo == CIPHER_ALGO_CAST5 ) return "CAST5"; diff --git a/cipher/des.c b/cipher/des.c index c2ca3f848..847a3473e 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -147,9 +147,6 @@ working_memcmp( const char *a, const char *b, size_t n ) #endif -/* Macros used by the info function. */ -#define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f)) -#define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f)) /* @@ -996,14 +993,16 @@ des_get_info( int algo, size_t *keylen, } } - if( algo == CIPHER_ALGO_3DES ) { *keylen = 192; *blocksize = 8; *contextsize = sizeof(struct _tripledes_ctx); - *r_setkey = FNCCAST_SETKEY(do_tripledes_setkey); - *r_encrypt= FNCCAST_CRYPT(do_tripledes_encrypt); - *r_decrypt= FNCCAST_CRYPT(do_tripledes_decrypt); + *(int (**)(struct _tripledes_ctx*, byte*, unsigned))r_setkey + = do_tripledes_setkey; + *(void (**)(struct _tripledes_ctx*, byte*, byte*))r_encrypt + = do_tripledes_encrypt; + *(void (**)(struct _tripledes_ctx*, byte*, byte*))r_decrypt + = do_tripledes_decrypt; return "3DES"; } return NULL; diff --git a/cipher/md5.c b/cipher/md5.c index bb930d042..eb09d261c 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -344,10 +344,10 @@ md5_get_info( int algo, size_t *contextsize, *r_asnoid = asn; *r_asnlen = DIM(asn); *r_mdlen = 16; - *r_init = (void (*)(void *))md5_init; - *r_write = (void (*)(void *, byte*, size_t))md5_write; - *r_final = (void (*)(void *))md5_final; - *r_read = (byte *(*)(void *))md5_read; + *(void (**)(MD5_CONTEXT *))r_init = md5_init; + *(void (**)(MD5_CONTEXT *, byte*, size_t))r_write = md5_write; + *(void (**)(MD5_CONTEXT *))r_final = md5_final; + *(byte *(**)(MD5_CONTEXT *))r_read = md5_read; return "MD5"; } diff --git a/cipher/rmd160.c b/cipher/rmd160.c index ecd65b35d..fba910d7e 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -562,10 +562,10 @@ rmd160_get_info( int algo, size_t *contextsize, *r_asnoid = asn; *r_asnlen = DIM(asn); *r_mdlen = 20; - *r_init = (void (*)(void *))rmd160_init; - *r_write = (void (*)(void *, byte*, size_t))rmd160_write; - *r_final = (void (*)(void *))rmd160_final; - *r_read = (byte *(*)(void *))rmd160_read; + *(void (**)(RMD160_CONTEXT *))r_init = rmd160_init; + *(void (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write; + *(void (**)(RMD160_CONTEXT *))r_final = rmd160_final; + *(byte *(**)(RMD160_CONTEXT *))r_read = rmd160_read; return "RIPEMD160"; } diff --git a/cipher/sha1.c b/cipher/sha1.c index 40ad62f1f..e47cc5e60 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -341,6 +341,10 @@ sha1_get_info( int algo, size_t *contextsize, *r_write = (void (*)(void *, byte*, size_t))sha1_write; *r_final = (void (*)(void *))sha1_final; *r_read = (byte *(*)(void *))sha1_read; + *(void (**)(SHA1_CONTEXT *))r_init = sha1_init; + *(void (**)(SHA1_CONTEXT *, byte*, size_t))r_write = sha1_write; + *(void (**)(SHA1_CONTEXT *))r_final = sha1_final; + *(byte *(**)(SHA1_CONTEXT *))r_read = sha1_read; return "SHA1"; } diff --git a/cipher/tiger.c b/cipher/tiger.c index 0765f0bbd..e4a7c4daa 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -899,10 +899,10 @@ tiger_get_info( int algo, size_t *contextsize, *r_asnoid = asn; *r_asnlen = DIM(asn); *r_mdlen = 24; - *r_init = (void (*)(void *))tiger_init; - *r_write = (void (*)(void *, byte*, size_t))tiger_write; - *r_final = (void (*)(void *))tiger_final; - *r_read = (byte *(*)(void *))tiger_read; + *(void (**)(TIGER_CONTEXT *))r_init = tiger_init; + *(void (**)(TIGER_CONTEXT *, byte*, size_t))r_write = tiger_write; + *(void (**)(TIGER_CONTEXT *))r_final = tiger_final; + *(byte *(**)(TIGER_CONTEXT *))r_read = tiger_read; return "TIGER"; } diff --git a/cipher/twofish.c b/cipher/twofish.c index 182f18c49..157a13735 100644 --- a/cipher/twofish.c +++ b/cipher/twofish.c @@ -35,10 +35,6 @@ /* Prototype for the self-test function. */ static const char *selftest(void); -/* Macros used by the info function. */ -#define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f)) -#define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f)) - /* Structure for an expanded Twofish key. s contains the key-dependent * S-boxes composed with the MDS matrix; w contains the eight "whitening" * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note @@ -991,16 +987,19 @@ twofish_get_info (int algo, size_t *keylen, *keylen = algo==10? 256 : 128; *blocksize = 16; *contextsize = sizeof (TWOFISH_context); - *r_setkey = FNCCAST_SETKEY (twofish_setkey); - *r_encrypt= FNCCAST_CRYPT (twofish_encrypt); - *r_decrypt= FNCCAST_CRYPT (twofish_decrypt); - - if( algo == 10 ) - return "TWOFISH"; - if (algo == 102) /* This algorithm number is assigned for - * experiments, so we can use it */ - return "TWOFISH128"; - return NULL; + *(int (**)(const TWOFISH_context*, byte*, unsigned))r_setkey + = twofish_setkey; + *(void (**)(const TWOFISH_context*, byte*, byte*))r_encrypt + = twofish_encrypt; + *(void (**)(const TWOFISH_context*, byte*, byte*))r_decrypt + = twofish_decrypt; + + if( algo == 10 ) + return "TWOFISH"; + if (algo == 102) /* This algorithm number is assigned for + * experiments, so we can use it */ + return "TWOFISH128"; + return NULL; } diff --git a/doc/DETAILS b/doc/DETAILS index 3007ab3de..0ab83ecdf 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -494,6 +494,15 @@ There is one enhancement used with the old style packet headers: + that this is the last packet. +GNU extensions to the S2K algorithm +=================================== +S2K mode 101 is used to identify these extensions. +After the hash algorithm the 3 bytes "GNU" are used to make +clear that these are extensions for GNU, the next bytes gives the +GNU protection mode - 1000. Defined modes are: + 1001 - do not store the secret part at all + + Usage of gdbm files for keyrings ================================ The key to store the keyblock is it's fingerprint, other records @@ -372,3 +372,30 @@ message and encrypt it again without this option. The option will be removed in 1.1, so better re-encrypt your message now. + Q: How can I used GnuPG in an automated environment? + A: You should use the option --batch and don't use passphrases as + there is usually no way to store it more secure than the secret + keyring itself. The suggested way to create the keys for the + automated envirionment ist: + On a secure machine: + 1. If you want to do automatic signing, create a signing subkey + for your key (edit menu, choose "addkey" and the DSA). + 2. Make sure that you use a passphrase (Needed by the current + implementation) + 3. gpg --export-secret-subkeys --no-comment foo >secring.auto + 4. Copy secring.auto and the public keyring to a test directory. + 5. Cd to this diectory + 6. gpg --homedir . --edit foo + and use "passwd" to remove the passphrase from the subkeys. + You may also want to remove all unused subkeys. + 7. copy secring.auto to a floppy and carry it to the + target box + On the target machine: + 8. Install secring.auto as secret keyring. + 9. Now you can start your new service. It is a good idea to + install some intrusion detection system so that you hopefully + get a notice of an successful intrusion, so that you in turn can + revoke all the subkeys installed on that machine and install new + subkeys. + + diff --git a/doc/OpenPGP b/doc/OpenPGP index c73eee4f8..ba44d87fb 100644 --- a/doc/OpenPGP +++ b/doc/OpenPGP @@ -33,6 +33,15 @@ which can be considered to be in compliance with RFC1991; this format is only created if a special option is active. + GnuPG uses a S2K mode of 101 for GNU extensions to the secret key + protection algorithms. This number is not defined in OpenPGP, but + given the fact that this number is in a range which used at many + other places in OpenPGP for private/experimenat algorithm identifiers, + this should be not a so bad choice. The 3 bytes "GNU" are used + to identify this as a GNU extension - see the file DETAILS for a + definition of the used data formats. + + Some Notes on OpenPGP / PGP Compatibility: ========================================== diff --git a/doc/gpg.sgml b/doc/gpg.sgml index 76f0415bf..ec160679b 100644 --- a/doc/gpg.sgml +++ b/doc/gpg.sgml @@ -27,7 +27,7 @@ --> -<!DOCTYPE RefEntry PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [ +<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [ <!entity ParmDir "<parameter>directory</parameter>"> <!entity ParmFile "<parameter>file</parameter>"> <!entity OptParmFile "<optional>&ParmFile;</optional>"> @@ -157,7 +157,7 @@ and the remaining files are the signed stuff. </para></listitem></varlistentry> <varlistentry> -<term>--verify-files <optional><optional><parameter/files/</optional> +<term>--verify-files <optional><parameter/files/</optional></term> <listitem><para> This is a special version of the --verify command which does not work with detached signatures. The command expects the files to bee verified either @@ -431,9 +431,14 @@ are not compatible to OpenPGP. <varlistentry> <term>--export-secret-keys &OptParmNames;</term> +<term>--export-secret-subkeys &OptParmNames;</term> <listitem><para> Same as --export, but does export the secret keys. This is normally not very useful and a security risk. +the second form of the command has the special property to +render the secret part of the primary key useless; this is +a GNU extension to OpenPGP and other implementations can +not be expected to successful import such a key. </para></listitem></varlistentry> @@ -1418,6 +1423,7 @@ constructed by cutting off the extension (".asc" or ".sig") of <term>GNUPGHOME</term> <listitem><para>If set directory used instead of "~/.gnupg".</para></listitem> </varlistentry> +<varlistentry> <term>http_proxy</term> <listitem><para>Only honored when the option --honor-http-proxy is set.</para></listitem> </varlistentry> diff --git a/g10/ChangeLog b/g10/ChangeLog index 05dd0b132..a428b72d5 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,14 @@ +Fri Jan 14 18:32:01 CET 2000 Werner Koch <[email protected]> + + * packet.h (STRING2KEY): Changed mode from byte to int. + * parse-packet.c (parse_key): Add the special GNU protection stuff + * build-packet.c (so_secret_key): Ditto. + * seckey-cert.c (do_check): Ditto. + * keyedit.c (change_passphrase): Ditto. + * export.c (export_secsubkeys): New. + (do_export_stream): Hack to export the primary key using mode 1001. + * g10.c: New command --export-secret-subkeys + Thu Jan 13 19:31:58 CET 2000 Werner Koch <[email protected]> * armor.c (is_armored): Check for 1-pass-sig packets. Reported by diff --git a/g10/build-packet.c b/g10/build-packet.c index 0a3bb74ee..3745d51c1 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -371,19 +371,30 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) else { iobuf_put(a, 0xff ); iobuf_put(a, sk->protect.algo ); - iobuf_put(a, sk->protect.s2k.mode ); - iobuf_put(a, sk->protect.s2k.hash_algo ); + if( sk->protect.s2k.mode >= 1000 ) { + iobuf_put(a, 101 ); + iobuf_put(a, sk->protect.s2k.hash_algo ); + iobuf_write(a, "GNU", 3 ); + iobuf_put(a, sk->protect.s2k.mode - 1000 ); + } + else { + iobuf_put(a, sk->protect.s2k.mode ); + iobuf_put(a, sk->protect.s2k.hash_algo ); + } if( sk->protect.s2k.mode == 1 || sk->protect.s2k.mode == 3 ) iobuf_write(a, sk->protect.s2k.salt, 8 ); if( sk->protect.s2k.mode == 3 ) iobuf_put(a, sk->protect.s2k.count ); - iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); + if( sk->protect.s2k.mode != 1001 ) + iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); } } else iobuf_put(a, 0 ); - if( sk->is_protected && sk->version >= 4 ) { + if( sk->protect.s2k.mode == 1001 ) + ; + else if( sk->is_protected && sk->version >= 4 ) { byte *p; assert( mpi_is_opaque( sk->skey[npkey] ) ); p = mpi_get_opaque( sk->skey[npkey], &i ); diff --git a/g10/export.c b/g10/export.c index 911a71599..106caa7d7 100644 --- a/g10/export.c +++ b/g10/export.c @@ -71,6 +71,12 @@ export_seckeys( STRLIST users ) return do_export( users, 1, 0 ); } +int +export_secsubkeys( STRLIST users ) +{ + return do_export( users, 2, 0 ); +} + static int do_export( STRLIST users, int secret, int onlyrfc ) { @@ -168,6 +174,16 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) } } + /* we can't apply GNU mode 1001 on an unprotected key */ + if( secret == 2 + && (node = find_kbnode( keyblock, PKT_SECRET_KEY )) + && !node->pkt->pkt.secret_key->is_protected ) + { + log_info(_("key %08lX: not protected - skipped\n"), + (ulong)keyid_from_sk( node->pkt->pkt.secret_key, NULL) ); + continue; + } + /* and write it */ for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { /* don't export any comment packets but those in the @@ -183,7 +199,20 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) continue; /* not exportable */ } - if( (rc = build_packet( out, node->pkt )) ) { + if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) { + /* we don't want to export the secret parts of the + * primary key, this is doen by using GNU protection mode 1001 + */ + int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode; + node->pkt->pkt.secret_key->protect.s2k.mode = 1001; + rc = build_packet( out, node->pkt ); + node->pkt->pkt.secret_key->protect.s2k.mode = save_mode; + } + else { + rc = build_packet( out, node->pkt ); + } + + if( rc ) { log_error("build_packet(%d) failed: %s\n", node->pkt->pkttype, g10_errstr(rc) ); rc = G10ERR_WRITE_FILE; @@ -88,6 +88,7 @@ enum cmd_and_opt_values { aNull = 0, aExport, aExportAll, aExportSecret, + aExportSecretSub, aCheckKeys, aGenRevoke, aPrimegen, @@ -217,6 +218,7 @@ static ARGPARSE_OPTS opts[] = { { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, { aExportAll, "export-all" , 256, "@" }, { aExportSecret, "export-secret-keys" , 256, "@" }, + { aExportSecretSub, "export-secret-subkeys" , 256, "@" }, { aImport, "import", 256 , N_("import/merge keys")}, { aFastImport, "fast-import", 256 , "@"}, { aListPackets, "list-packets",256,N_("list only the sequence of packets")}, @@ -697,6 +699,7 @@ main( int argc, char **argv ) case aListKeys: set_cmd( &cmd, aListKeys); break; case aListSigs: set_cmd( &cmd, aListSigs); break; case aExportSecret: set_cmd( &cmd, aExportSecret); break; + case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break; case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey); greeting=1; break; case aDeleteKey: set_cmd( &cmd, aDeleteKey); greeting=1; break; @@ -1271,6 +1274,14 @@ main( int argc, char **argv ) free_strlist(sl); break; + case aExportSecretSub: + sl = NULL; + for( ; argc; argc--, argv++ ) + add_to_strlist2( &sl, *argv, utf8_strings ); + export_secsubkeys( sl ); + free_strlist(sl); + break; + case aGenRevoke: if( argc != 1 ) wrong_args("--gen-revoke user-id"); diff --git a/g10/keyedit.c b/g10/keyedit.c index e5157f0ca..bed757922 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -407,6 +407,7 @@ change_passphrase( KBNODE keyblock ) KBNODE node; PKT_secret_key *sk; char *passphrase = NULL; + int no_primary_secrets = 0; node = find_kbnode( keyblock, PKT_SECRET_KEY ); if( !node ) { @@ -423,10 +424,16 @@ change_passphrase( KBNODE keyblock ) tty_printf(_("This key is not protected.\n")); break; default: - tty_printf(_("Key is protected.\n")); - rc = check_secret_key( sk, 0 ); - if( !rc ) - passphrase = get_last_passphrase(); + if( sk->protect.s2k.mode == 1001 ) { + tty_printf(_("Secret parts of primary key are not available.\n")); + no_primary_secrets = 1; + } + else { + tty_printf(_("Key is protected.\n")); + rc = check_secret_key( sk, 0 ); + if( !rc ) + passphrase = get_last_passphrase(); + } break; } @@ -436,6 +443,8 @@ change_passphrase( KBNODE keyblock ) PKT_secret_key *subsk = node->pkt->pkt.secret_key; set_next_passphrase( passphrase ); rc = check_secret_key( subsk, 0 ); + if( !rc && !passphrase ) + passphrase = get_last_passphrase(); } } @@ -465,9 +474,12 @@ change_passphrase( KBNODE keyblock ) break; } else { /* okay */ - sk->protect.algo = dek->algo; - sk->protect.s2k = *s2k; - rc = protect_secret_key( sk, dek ); + rc = 0; + if( !no_primary_secrets ) { + sk->protect.algo = dek->algo; + sk->protect.s2k = *s2k; + rc = protect_secret_key( sk, dek ); + } for(node=keyblock; !rc && node; node = node->next ) { if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { PKT_secret_key *subsk = node->pkt->pkt.secret_key; diff --git a/g10/main.h b/g10/main.h index 4be23aecd..6188cefc9 100644 --- a/g10/main.h +++ b/g10/main.h @@ -124,6 +124,7 @@ int collapse_uids( KBNODE *keyblock ); int export_pubkeys( STRLIST users, int onlyrfc ); int export_pubkeys_stream( IOBUF out, STRLIST users, int onlyrfc ); int export_seckeys( STRLIST users ); +int export_secsubkeys( STRLIST users ); /* dearmor.c --*/ int dearmor_file( const char *fname ); diff --git a/g10/packet.h b/g10/packet.h index 302b99289..3a05f0d52 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -54,7 +54,7 @@ typedef enum { typedef struct packet_struct PACKET; typedef struct { - byte mode; + int mode; byte hash_algo; byte salt[8]; u32 count; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 03e56708c..93dc094db 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1324,6 +1324,24 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, sk->protect.algo = iobuf_get_noeof(inp); pktlen--; sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--; sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--; + /* check for the special GNU extension */ + if( is_v4 && sk->protect.s2k.mode == 101 ) { + for(i=0; i < 4 && pktlen; i++, pktlen-- ) + temp[i] = iobuf_get_noeof(inp); + if( i < 4 || memcmp( temp, "GNU", 3 ) ) { + if( list_mode ) + printf( "\tunknown S2K %d\n", + sk->protect.s2k.mode ); + rc = G10ERR_INVALID_PACKET; + goto leave; + } + /* here we know that it is a gnu extension + * What follows is the GNU protection mode: + * All values have special meanings + * and they are mapped in the mode with a base of 1000. + */ + sk->protect.s2k.mode = 1000 + temp[3]; + } switch( sk->protect.s2k.mode ) { case 1: case 3: @@ -1339,10 +1357,13 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, break; case 3: if( list_mode ) printf( "\titer+salt S2K" ); break; + case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" ); + break; default: if( list_mode ) - printf( "\tunknown S2K %d\n", - sk->protect.s2k.mode ); + printf( "\tunknown %sS2K %d\n", + sk->protect.s2k.mode < 1000? "":"GNU ", + sk->protect.s2k.mode ); rc = G10ERR_INVALID_PACKET; goto leave; } @@ -1395,6 +1416,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, default: sk->protect.ivlen = 8; } + if( sk->protect.s2k.mode == 1001 ) + sk->protect.ivlen = 0; + if( pktlen < sk->protect.ivlen ) { rc = G10ERR_INVALID_PACKET; goto leave; @@ -1415,7 +1439,12 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, * If the user is so careless, not to protect his secret key, * we can assume, that he operates an open system :=(. * So we put the key into secure memory when we unprotect it. */ - if( is_v4 && sk->is_protected ) { + if( sk->protect.s2k.mode == 1001 ) { + /* better set some dummy stuff here */ + sk->skey[npkey] = mpi_set_opaque(NULL, m_strdup("dummydata"), 10); + pktlen = 0; + } + else if( is_v4 && sk->is_protected ) { /* ugly; the length is encrypted too, so we read all * stuff up to the end of the packet into the first * skey element */ diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index a8fae04d6..91511c68f 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -49,6 +49,10 @@ do_check( PKT_secret_key *sk ) CIPHER_HANDLE cipher_hd=NULL; PKT_secret_key *save_sk; + if( sk->protect.s2k.mode == 1001 ) { + log_info(_("secret key parts are not available\n")); + return G10ERR_GENERAL; + } if( sk->protect.algo == CIPHER_ALGO_NONE ) BUG(); if( check_cipher_algo( sk->protect.algo ) ) { diff --git a/mpi/ChangeLog b/mpi/ChangeLog index ee1cd06fe..7ef20de40 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -5,7 +5,7 @@ Thu Jan 13 19:31:58 CET 2000 Werner Koch <[email protected]> (mpihelp_mul_karatsuba_case): New. (mpihelp_mul): Splitted to make use of the new functions. * mpi-pow.c (mpi_powm): Make use of the new splitted function - to avoid multiple allocation of temorary memory during the + to avoid multiple allocation of temporary memory during the karatsuba operations. * mpi_mpow.c: Removed the unused Barrett code. |