mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
See ChangeLog: Fri Jan 14 18:32:01 CET 2000 Werner Koch
This commit is contained in:
parent
e8164f20ab
commit
932049cbe4
25 changed files with 249 additions and 65 deletions
|
@ -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>
|
||||
|
||||
* armor.c (is_armored): Check for 1-pass-sig packets. Reported by
|
||||
|
|
|
@ -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 );
|
||||
|
|
31
g10/export.c
31
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;
|
||||
|
|
11
g10/g10.c
11
g10/g10.c
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ) ) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue