diff options
Diffstat (limited to 'g10/keyedit.c')
-rw-r--r-- | g10/keyedit.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/g10/keyedit.c b/g10/keyedit.c index 77da1977b..f5c95ea32 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -169,10 +169,6 @@ remove_keysigs( KBNODE keyblock, u32 *keyid, int all ) && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) { PKT_signature *sig = node->pkt->pkt.signature; - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { - /* fixme: skip self-sig */ - } - tty_printf("\n \"%08lX %s ", sig->keyid[1], datestr_from_sig(sig)); if( node->flag & 6 ) @@ -349,6 +345,7 @@ sign_key( const char *username, STRLIST locusr ) rc = make_keysig_packet( &sig, pkc, node->pkt->pkt.user_id, + NULL, skc_rover->skc, 0x10, 0 ); if( rc ) { @@ -568,9 +565,10 @@ change_passphrase( const char *username ) KBNODE node; KBPOS kbpos; PKT_secret_cert *skc; - u32 skc_keyid[2]; + u32 keyid[2]; char *answer; int changed=0; + char *passphrase = NULL; /* find the userid */ rc = find_secret_keyblock_byname( &kbpos, username ); @@ -595,18 +593,28 @@ change_passphrase( const char *username ) } skc = node->pkt->pkt.secret_cert; - keyid_from_skc( skc, skc_keyid ); + keyid_from_skc( skc, keyid ); tty_printf("sec %4u%c/%08lX %s ", nbits_from_skc( skc ), pubkey_letter( skc->pubkey_algo ), - skc_keyid[1], datestr_from_skc(skc) ); + keyid[1], datestr_from_skc(skc) ); { size_t n; - char *p = get_user_id( skc_keyid, &n ); + char *p = get_user_id( keyid, &n ); tty_print_string( p, n ); m_free(p); tty_printf("\n"); } + for(node=keyblock; node; node = node->next ) { + if( node->pkt->pkttype == PKT_SECKEY_SUBCERT ) { + PKT_secret_cert *subskc = node->pkt->pkt.secret_cert; + keyid_from_skc( subskc, keyid ); + tty_printf("sub %4u%c/%08lX %s\n", + nbits_from_skc( subskc ), + pubkey_letter( subskc->pubkey_algo ), + keyid[1], datestr_from_skc(subskc) ); + } + } clear_kbnode_flags( keyblock ); switch( is_secret_key_protected( skc ) ) { @@ -619,10 +627,21 @@ change_passphrase( const char *username ) default: tty_printf("Key is protected.\n"); rc = check_secret_key( skc ); + if( !rc ) + passphrase = get_last_passphrase(); break; } - /* fixme: unprotect all subkeys */ + /* unprotect all subkeys (use the supplied passphrase or ask)*/ + for(node=keyblock; node; node = node->next ) { + if( node->pkt->pkttype == PKT_SECKEY_SUBCERT ) { + PKT_secret_cert *subskc = node->pkt->pkt.secret_cert; + set_next_passphrase( passphrase ); + rc = check_secret_key( subskc ); + if( rc ) + break; + } + } if( rc ) tty_printf("Can't edit this key: %s\n", g10_errstr(rc)); @@ -632,6 +651,7 @@ change_passphrase( const char *username ) tty_printf(_("Enter the new passphrase for this secret key.\n\n") ); + set_next_passphrase( NULL ); for(;;) { s2k->mode = 1; s2k->hash_algo = DIGEST_ALGO_RMD160; @@ -651,10 +671,17 @@ change_passphrase( const char *username ) break; } else { /* okay */ - /* fixme: protect all subkeys too */ skc->protect.algo = dek->algo; skc->protect.s2k = *s2k; rc = protect_secret_key( skc, dek ); + for(node=keyblock; !rc && node; node = node->next ) { + if( node->pkt->pkttype == PKT_SECKEY_SUBCERT ) { + PKT_secret_cert *subskc = node->pkt->pkt.secret_cert; + subskc->protect.algo = dek->algo; + subskc->protect.s2k = *s2k; + rc = protect_secret_key( subskc, dek ); + } + } if( rc ) log_error("protect_secret_key failed: %s\n", g10_errstr(rc) ); else @@ -676,7 +703,9 @@ change_passphrase( const char *username ) } leave: + m_free( passphrase ); release_kbnode( keyblock ); + set_next_passphrase( NULL ); return rc; } @@ -689,14 +718,16 @@ change_passphrase( const char *username ) */ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, - PKT_user_id *uid, PKT_secret_cert *skc, + PKT_user_id *uid, PKT_public_cert *subpkc, + PKT_secret_cert *skc, int sigclass, int digest_algo ) { PKT_signature *sig; int rc=0; MD_HANDLE md; - assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x20 ); + assert( (sigclass >= 0x10 && sigclass <= 0x13) + || sigclass == 0x20 || sigclass == 0x18 ); if( !digest_algo ) { switch( skc->pubkey_algo ) { case PUBKEY_ALGO_DSA: digest_algo = DIGEST_ALGO_SHA1; break; @@ -706,11 +737,13 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, } } md = md_open( digest_algo, 0 ); - /*md_start_debug( md, "make" );*/ /* hash the public key certificate and the user id */ hash_public_cert( md, pkc ); - if( sigclass != 0x20 ) { + if( sigclass == 0x18 ) { /* subkey binding */ + hash_public_cert( md, subpkc ); + } + else if( sigclass != 0x20 ) { if( skc->version >=4 ) { byte buf[5]; buf[0] = 0xb4; /* indicates a userid packet */ @@ -759,7 +792,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, /* add some magic */ buf[0] = sig->version; buf[1] = 0xff; - buf[2] = n >> 24; /* hmmm, n is only 16 bit, so tthis is always 0 */ + buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */ buf[3] = n >> 16; buf[4] = n >> 8; buf[5] = n; |