1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-09-21 15:01:41 +02:00

See ChangeLog: Fri Jan 14 18:32:01 CET 2000 Werner Koch

This commit is contained in:
Werner Koch 2000-01-14 17:26:00 +00:00
parent e8164f20ab
commit 932049cbe4
25 changed files with 249 additions and 65 deletions

View File

@ -1,6 +1,6 @@
Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de> Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
* 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. a dash in it. Suggested by Dave Dykstra.
Thu Dec 16 10:07:58 CET 1999 Werner Koch <wk@gnupg.de> Thu Dec 16 10:07:58 CET 1999 Werner Koch <wk@gnupg.de>

10
NEWS
View File

@ -1,3 +1,5 @@
Noteworthy changes in the current test release
----------------------------------------------
* Some fixes for the W32 version * Some fixes for the W32 version
@ -7,6 +9,14 @@
* New encryption keys are generated in way which allows a much * New encryption keys are generated in way which allows a much
faster decryption. 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) Noteworthy changes in version 1.0.1 (1999-12-16)
----------------------------------- -----------------------------------

View File

@ -1,3 +1,15 @@
Fri Jan 14 18:32:01 CET 2000 Werner Koch <wk@gnupg.de>
* 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 <wk@gnupg.de> Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
* elgamal.c (wiener_map): New. * elgamal.c (wiener_map): New.
@ -5,7 +17,7 @@ Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
(generate): Calculate the qbits using the wiener map and (generate): Calculate the qbits using the wiener map and
choose an x at a size comparable to the one choosen in gen_k 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. cases when too much random is requested in one call.
* Makefile.am (tiger): Replaced -O1 by -O. Suggested by Alec Habig. * Makefile.am (tiger): Replaced -O1 by -O. Suggested by Alec Habig.

View File

@ -43,9 +43,6 @@
#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */ #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_BLOCKSIZE 8
#define BLOWFISH_ROUNDS 16 #define BLOWFISH_ROUNDS 16
@ -584,9 +581,12 @@ blowfish_get_info( int algo, size_t *keylen,
*keylen = 128; *keylen = 128;
*blocksize = BLOWFISH_BLOCKSIZE; *blocksize = BLOWFISH_BLOCKSIZE;
*contextsize = sizeof(BLOWFISH_context); *contextsize = sizeof(BLOWFISH_context);
*r_setkey = FNCCAST_SETKEY(bf_setkey); *(int (**)(BLOWFISH_context*, byte*, unsigned))r_setkey
*r_encrypt= FNCCAST_CRYPT(encrypt_block); = bf_setkey;
*r_decrypt= FNCCAST_CRYPT(decrypt_block); *(void (**)(BLOWFISH_context*, byte*, byte*))r_encrypt
= encrypt_block;
*(void (**)(BLOWFISH_context*, byte*, byte*))r_decrypt
= decrypt_block;
if( algo == CIPHER_ALGO_BLOWFISH ) if( algo == CIPHER_ALGO_BLOWFISH )
return "BLOWFISH"; return "BLOWFISH";

View File

@ -46,9 +46,6 @@
#define CIPHER_ALGO_CAST5 3 #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 #define CAST5_BLOCKSIZE 8
typedef struct { typedef struct {
@ -610,9 +607,13 @@ cast5_get_info( int algo, size_t *keylen,
*keylen = 128; *keylen = 128;
*blocksize = CAST5_BLOCKSIZE; *blocksize = CAST5_BLOCKSIZE;
*contextsize = sizeof(CAST5_context); *contextsize = sizeof(CAST5_context);
*r_setkey = FNCCAST_SETKEY(cast_setkey); *(int (**)(CAST5_context*, byte*, unsigned))r_setkey
*r_encrypt= FNCCAST_CRYPT(encrypt_block); = cast_setkey;
*r_decrypt= FNCCAST_CRYPT(decrypt_block); *(void (**)(CAST5_context*, byte*, byte*))r_encrypt
= encrypt_block;
*(void (**)(CAST5_context*, byte*, byte*))r_decrypt
= decrypt_block;
if( algo == CIPHER_ALGO_CAST5 ) if( algo == CIPHER_ALGO_CAST5 )
return "CAST5"; return "CAST5";

View File

@ -147,9 +147,6 @@ working_memcmp( const char *a, const char *b, size_t n )
#endif #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 ) { if( algo == CIPHER_ALGO_3DES ) {
*keylen = 192; *keylen = 192;
*blocksize = 8; *blocksize = 8;
*contextsize = sizeof(struct _tripledes_ctx); *contextsize = sizeof(struct _tripledes_ctx);
*r_setkey = FNCCAST_SETKEY(do_tripledes_setkey); *(int (**)(struct _tripledes_ctx*, byte*, unsigned))r_setkey
*r_encrypt= FNCCAST_CRYPT(do_tripledes_encrypt); = do_tripledes_setkey;
*r_decrypt= FNCCAST_CRYPT(do_tripledes_decrypt); *(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 "3DES";
} }
return NULL; return NULL;

View File

@ -344,10 +344,10 @@ md5_get_info( int algo, size_t *contextsize,
*r_asnoid = asn; *r_asnoid = asn;
*r_asnlen = DIM(asn); *r_asnlen = DIM(asn);
*r_mdlen = 16; *r_mdlen = 16;
*r_init = (void (*)(void *))md5_init; *(void (**)(MD5_CONTEXT *))r_init = md5_init;
*r_write = (void (*)(void *, byte*, size_t))md5_write; *(void (**)(MD5_CONTEXT *, byte*, size_t))r_write = md5_write;
*r_final = (void (*)(void *))md5_final; *(void (**)(MD5_CONTEXT *))r_final = md5_final;
*r_read = (byte *(*)(void *))md5_read; *(byte *(**)(MD5_CONTEXT *))r_read = md5_read;
return "MD5"; return "MD5";
} }

View File

@ -562,10 +562,10 @@ rmd160_get_info( int algo, size_t *contextsize,
*r_asnoid = asn; *r_asnoid = asn;
*r_asnlen = DIM(asn); *r_asnlen = DIM(asn);
*r_mdlen = 20; *r_mdlen = 20;
*r_init = (void (*)(void *))rmd160_init; *(void (**)(RMD160_CONTEXT *))r_init = rmd160_init;
*r_write = (void (*)(void *, byte*, size_t))rmd160_write; *(void (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write;
*r_final = (void (*)(void *))rmd160_final; *(void (**)(RMD160_CONTEXT *))r_final = rmd160_final;
*r_read = (byte *(*)(void *))rmd160_read; *(byte *(**)(RMD160_CONTEXT *))r_read = rmd160_read;
return "RIPEMD160"; return "RIPEMD160";
} }

View File

@ -341,6 +341,10 @@ sha1_get_info( int algo, size_t *contextsize,
*r_write = (void (*)(void *, byte*, size_t))sha1_write; *r_write = (void (*)(void *, byte*, size_t))sha1_write;
*r_final = (void (*)(void *))sha1_final; *r_final = (void (*)(void *))sha1_final;
*r_read = (byte *(*)(void *))sha1_read; *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"; return "SHA1";
} }

View File

@ -899,10 +899,10 @@ tiger_get_info( int algo, size_t *contextsize,
*r_asnoid = asn; *r_asnoid = asn;
*r_asnlen = DIM(asn); *r_asnlen = DIM(asn);
*r_mdlen = 24; *r_mdlen = 24;
*r_init = (void (*)(void *))tiger_init; *(void (**)(TIGER_CONTEXT *))r_init = tiger_init;
*r_write = (void (*)(void *, byte*, size_t))tiger_write; *(void (**)(TIGER_CONTEXT *, byte*, size_t))r_write = tiger_write;
*r_final = (void (*)(void *))tiger_final; *(void (**)(TIGER_CONTEXT *))r_final = tiger_final;
*r_read = (byte *(*)(void *))tiger_read; *(byte *(**)(TIGER_CONTEXT *))r_read = tiger_read;
return "TIGER"; return "TIGER";
} }

View File

@ -35,10 +35,6 @@
/* Prototype for the self-test function. */ /* Prototype for the self-test function. */
static const char *selftest(void); 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 /* Structure for an expanded Twofish key. s contains the key-dependent
* S-boxes composed with the MDS matrix; w contains the eight "whitening" * 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 * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
@ -991,9 +987,12 @@ twofish_get_info (int algo, size_t *keylen,
*keylen = algo==10? 256 : 128; *keylen = algo==10? 256 : 128;
*blocksize = 16; *blocksize = 16;
*contextsize = sizeof (TWOFISH_context); *contextsize = sizeof (TWOFISH_context);
*r_setkey = FNCCAST_SETKEY (twofish_setkey); *(int (**)(const TWOFISH_context*, byte*, unsigned))r_setkey
*r_encrypt= FNCCAST_CRYPT (twofish_encrypt); = twofish_setkey;
*r_decrypt= FNCCAST_CRYPT (twofish_decrypt); *(void (**)(const TWOFISH_context*, byte*, byte*))r_encrypt
= twofish_encrypt;
*(void (**)(const TWOFISH_context*, byte*, byte*))r_decrypt
= twofish_decrypt;
if( algo == 10 ) if( algo == 10 )
return "TWOFISH"; return "TWOFISH";

View File

@ -494,6 +494,15 @@ There is one enhancement used with the old style packet headers:
+ that this is the last packet. + 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 Usage of gdbm files for keyrings
================================ ================================
The key to store the keyblock is it's fingerprint, other records The key to store the keyblock is it's fingerprint, other records

27
doc/FAQ
View File

@ -372,3 +372,30 @@
message and encrypt it again without this option. The option will message and encrypt it again without this option. The option will
be removed in 1.1, so better re-encrypt your message now. 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.

View File

@ -33,6 +33,15 @@
which can be considered to be in compliance with RFC1991; this which can be considered to be in compliance with RFC1991; this
format is only created if a special option is active. 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: Some Notes on OpenPGP / PGP Compatibility:
========================================== ==========================================

View File

@ -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 ParmDir "<parameter>directory</parameter>">
<!entity ParmFile "<parameter>file</parameter>"> <!entity ParmFile "<parameter>file</parameter>">
<!entity OptParmFile "<optional>&ParmFile;</optional>"> <!entity OptParmFile "<optional>&ParmFile;</optional>">
@ -157,7 +157,7 @@ and the remaining files are the signed stuff.
</para></listitem></varlistentry> </para></listitem></varlistentry>
<varlistentry> <varlistentry>
<term>--verify-files <optional><optional><parameter/files/</optional> <term>--verify-files <optional><parameter/files/</optional></term>
<listitem><para> <listitem><para>
This is a special version of the --verify command which does not work with 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 detached signatures. The command expects the files to bee verified either
@ -431,9 +431,14 @@ are not compatible to OpenPGP.
<varlistentry> <varlistentry>
<term>--export-secret-keys &OptParmNames;</term> <term>--export-secret-keys &OptParmNames;</term>
<term>--export-secret-subkeys &OptParmNames;</term>
<listitem><para> <listitem><para>
Same as --export, but does export the secret keys. Same as --export, but does export the secret keys.
This is normally not very useful and a security risk. 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> </para></listitem></varlistentry>
@ -1418,6 +1423,7 @@ constructed by cutting off the extension (".asc" or ".sig") of
<term>GNUPGHOME</term> <term>GNUPGHOME</term>
<listitem><para>If set directory used instead of "~/.gnupg".</para></listitem> <listitem><para>If set directory used instead of "~/.gnupg".</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>http_proxy</term> <term>http_proxy</term>
<listitem><para>Only honored when the option --honor-http-proxy is set.</para></listitem> <listitem><para>Only honored when the option --honor-http-proxy is set.</para></listitem>
</varlistentry> </varlistentry>

View File

@ -1,3 +1,14 @@
Fri Jan 14 18:32:01 CET 2000 Werner Koch <wk@gnupg.de>
* 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 <wk@gnupg.de> Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
* armor.c (is_armored): Check for 1-pass-sig packets. Reported by * armor.c (is_armored): Check for 1-pass-sig packets. Reported by

View File

@ -371,19 +371,30 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
else { else {
iobuf_put(a, 0xff ); iobuf_put(a, 0xff );
iobuf_put(a, sk->protect.algo ); iobuf_put(a, sk->protect.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.mode );
iobuf_put(a, sk->protect.s2k.hash_algo ); iobuf_put(a, sk->protect.s2k.hash_algo );
}
if( sk->protect.s2k.mode == 1 if( sk->protect.s2k.mode == 1
|| sk->protect.s2k.mode == 3 ) || sk->protect.s2k.mode == 3 )
iobuf_write(a, sk->protect.s2k.salt, 8 ); iobuf_write(a, sk->protect.s2k.salt, 8 );
if( sk->protect.s2k.mode == 3 ) if( sk->protect.s2k.mode == 3 )
iobuf_put(a, sk->protect.s2k.count ); iobuf_put(a, sk->protect.s2k.count );
if( sk->protect.s2k.mode != 1001 )
iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
} }
} }
else else
iobuf_put(a, 0 ); 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; byte *p;
assert( mpi_is_opaque( sk->skey[npkey] ) ); assert( mpi_is_opaque( sk->skey[npkey] ) );
p = mpi_get_opaque( sk->skey[npkey], &i ); p = mpi_get_opaque( sk->skey[npkey], &i );

View File

@ -71,6 +71,12 @@ export_seckeys( STRLIST users )
return do_export( users, 1, 0 ); return do_export( users, 1, 0 );
} }
int
export_secsubkeys( STRLIST users )
{
return do_export( users, 2, 0 );
}
static int static int
do_export( STRLIST users, int secret, int onlyrfc ) 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 */ /* and write it */
for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
/* don't export any comment packets but those in the /* 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 */ 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", log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) ); node->pkt->pkttype, g10_errstr(rc) );
rc = G10ERR_WRITE_FILE; rc = G10ERR_WRITE_FILE;

View File

@ -88,6 +88,7 @@ enum cmd_and_opt_values { aNull = 0,
aExport, aExport,
aExportAll, aExportAll,
aExportSecret, aExportSecret,
aExportSecretSub,
aCheckKeys, aCheckKeys,
aGenRevoke, aGenRevoke,
aPrimegen, aPrimegen,
@ -217,6 +218,7 @@ static ARGPARSE_OPTS opts[] = {
{ aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") },
{ aExportAll, "export-all" , 256, "@" }, { aExportAll, "export-all" , 256, "@" },
{ aExportSecret, "export-secret-keys" , 256, "@" }, { aExportSecret, "export-secret-keys" , 256, "@" },
{ aExportSecretSub, "export-secret-subkeys" , 256, "@" },
{ aImport, "import", 256 , N_("import/merge keys")}, { aImport, "import", 256 , N_("import/merge keys")},
{ aFastImport, "fast-import", 256 , "@"}, { aFastImport, "fast-import", 256 , "@"},
{ aListPackets, "list-packets",256,N_("list only the sequence of packets")}, { 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 aListKeys: set_cmd( &cmd, aListKeys); break;
case aListSigs: set_cmd( &cmd, aListSigs); break; case aListSigs: set_cmd( &cmd, aListSigs); break;
case aExportSecret: set_cmd( &cmd, aExportSecret); break; case aExportSecret: set_cmd( &cmd, aExportSecret); break;
case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey); case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey);
greeting=1; break; greeting=1; break;
case aDeleteKey: set_cmd( &cmd, aDeleteKey); greeting=1; break; case aDeleteKey: set_cmd( &cmd, aDeleteKey); greeting=1; break;
@ -1271,6 +1274,14 @@ main( int argc, char **argv )
free_strlist(sl); free_strlist(sl);
break; 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: case aGenRevoke:
if( argc != 1 ) if( argc != 1 )
wrong_args("--gen-revoke user-id"); wrong_args("--gen-revoke user-id");

View File

@ -407,6 +407,7 @@ change_passphrase( KBNODE keyblock )
KBNODE node; KBNODE node;
PKT_secret_key *sk; PKT_secret_key *sk;
char *passphrase = NULL; char *passphrase = NULL;
int no_primary_secrets = 0;
node = find_kbnode( keyblock, PKT_SECRET_KEY ); node = find_kbnode( keyblock, PKT_SECRET_KEY );
if( !node ) { if( !node ) {
@ -423,10 +424,16 @@ change_passphrase( KBNODE keyblock )
tty_printf(_("This key is not protected.\n")); tty_printf(_("This key is not protected.\n"));
break; break;
default: default:
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")); tty_printf(_("Key is protected.\n"));
rc = check_secret_key( sk, 0 ); rc = check_secret_key( sk, 0 );
if( !rc ) if( !rc )
passphrase = get_last_passphrase(); passphrase = get_last_passphrase();
}
break; break;
} }
@ -436,6 +443,8 @@ change_passphrase( KBNODE keyblock )
PKT_secret_key *subsk = node->pkt->pkt.secret_key; PKT_secret_key *subsk = node->pkt->pkt.secret_key;
set_next_passphrase( passphrase ); set_next_passphrase( passphrase );
rc = check_secret_key( subsk, 0 ); rc = check_secret_key( subsk, 0 );
if( !rc && !passphrase )
passphrase = get_last_passphrase();
} }
} }
@ -465,9 +474,12 @@ change_passphrase( KBNODE keyblock )
break; break;
} }
else { /* okay */ else { /* okay */
rc = 0;
if( !no_primary_secrets ) {
sk->protect.algo = dek->algo; sk->protect.algo = dek->algo;
sk->protect.s2k = *s2k; sk->protect.s2k = *s2k;
rc = protect_secret_key( sk, dek ); rc = protect_secret_key( sk, dek );
}
for(node=keyblock; !rc && node; node = node->next ) { for(node=keyblock; !rc && node; node = node->next ) {
if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
PKT_secret_key *subsk = node->pkt->pkt.secret_key; PKT_secret_key *subsk = node->pkt->pkt.secret_key;

View File

@ -124,6 +124,7 @@ int collapse_uids( KBNODE *keyblock );
int export_pubkeys( STRLIST users, int onlyrfc ); int export_pubkeys( STRLIST users, int onlyrfc );
int export_pubkeys_stream( IOBUF out, STRLIST users, int onlyrfc ); int export_pubkeys_stream( IOBUF out, STRLIST users, int onlyrfc );
int export_seckeys( STRLIST users ); int export_seckeys( STRLIST users );
int export_secsubkeys( STRLIST users );
/* dearmor.c --*/ /* dearmor.c --*/
int dearmor_file( const char *fname ); int dearmor_file( const char *fname );

View File

@ -54,7 +54,7 @@ typedef enum {
typedef struct packet_struct PACKET; typedef struct packet_struct PACKET;
typedef struct { typedef struct {
byte mode; int mode;
byte hash_algo; byte hash_algo;
byte salt[8]; byte salt[8];
u32 count; u32 count;

View File

@ -1324,6 +1324,24 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
sk->protect.algo = iobuf_get_noeof(inp); pktlen--; sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--; sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
sk->protect.s2k.hash_algo = 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 ) { switch( sk->protect.s2k.mode ) {
case 1: case 1:
case 3: case 3:
@ -1339,9 +1357,12 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
break; break;
case 3: if( list_mode ) printf( "\titer+salt S2K" ); case 3: if( list_mode ) printf( "\titer+salt S2K" );
break; break;
case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" );
break;
default: default:
if( list_mode ) if( list_mode )
printf( "\tunknown S2K %d\n", printf( "\tunknown %sS2K %d\n",
sk->protect.s2k.mode < 1000? "":"GNU ",
sk->protect.s2k.mode ); sk->protect.s2k.mode );
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; goto leave;
@ -1395,6 +1416,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
default: default:
sk->protect.ivlen = 8; sk->protect.ivlen = 8;
} }
if( sk->protect.s2k.mode == 1001 )
sk->protect.ivlen = 0;
if( pktlen < sk->protect.ivlen ) { if( pktlen < sk->protect.ivlen ) {
rc = G10ERR_INVALID_PACKET; rc = G10ERR_INVALID_PACKET;
goto leave; 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, * If the user is so careless, not to protect his secret key,
* we can assume, that he operates an open system :=(. * we can assume, that he operates an open system :=(.
* So we put the key into secure memory when we unprotect it. */ * 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 /* ugly; the length is encrypted too, so we read all
* stuff up to the end of the packet into the first * stuff up to the end of the packet into the first
* skey element */ * skey element */

View File

@ -49,6 +49,10 @@ do_check( PKT_secret_key *sk )
CIPHER_HANDLE cipher_hd=NULL; CIPHER_HANDLE cipher_hd=NULL;
PKT_secret_key *save_sk; 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 ) if( sk->protect.algo == CIPHER_ALGO_NONE )
BUG(); BUG();
if( check_cipher_algo( sk->protect.algo ) ) { if( check_cipher_algo( sk->protect.algo ) ) {

View File

@ -5,7 +5,7 @@ Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
(mpihelp_mul_karatsuba_case): New. (mpihelp_mul_karatsuba_case): New.
(mpihelp_mul): Splitted to make use of the new functions. (mpihelp_mul): Splitted to make use of the new functions.
* mpi-pow.c (mpi_powm): Make use of the new splitted function * 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. karatsuba operations.
* mpi_mpow.c: Removed the unused Barrett code. * mpi_mpow.c: Removed the unused Barrett code.