summaryrefslogtreecommitdiffstats
path: root/g10/keyedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/keyedit.c')
-rw-r--r--g10/keyedit.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/g10/keyedit.c b/g10/keyedit.c
index a475ed813..271e26d46 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -191,8 +191,10 @@ remove_keysigs( KBNODE keyblock, u32 *keyid, int all )
else if( node->flag & 4 )
tty_printf("The signature could not be checked!\n");
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
+ if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
+ tty_printf("Skipped self-signature\n");
continue; /* do not remove self-signatures */
+ }
answer = tty_get("\nRemove this signature? ");
tty_kill_prompt();
@@ -348,8 +350,7 @@ sign_key( const char *username, STRLIST locusr )
rc = make_keysig_packet( &sig, pkc,
node->pkt->pkt.user_id,
skc_rover->skc,
- 0x10,
- DIGEST_ALGO_RMD160 );
+ 0x10, 0 );
if( rc ) {
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc));
goto leave;
@@ -684,6 +685,7 @@ change_passphrase( const char *username )
* Create a signature packet for the given public key certificate
* and the user id and return it in ret_sig. User signature class SIGCLASS
* user-id is not used (and may be NULL if sigclass is 0x20)
+ * If digest_algo is 0 the function selects an appropriate one.
*/
int
make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
@@ -695,25 +697,75 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
MD_HANDLE md;
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x20 );
+ if( !digest_algo ) {
+ switch( skc->pubkey_algo ) {
+ case PUBKEY_ALGO_DSA: digest_algo = DIGEST_ALGO_SHA1; break;
+ case PUBKEY_ALGO_RSA_S:
+ case PUBKEY_ALGO_RSA: digest_algo = DIGEST_ALGO_MD5; break;
+ default: digest_algo = DIGEST_ALGO_RMD160; break;
+ }
+ }
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 != 0x20 ) {
+ if( skc->version >=4 ) {
+ byte buf[5];
+ buf[0] = 0xb4; /* indicates a userid packet */
+ buf[1] = uid->len >> 24; /* always use 4 length bytes */
+ buf[2] = uid->len >> 16;
+ buf[3] = uid->len >> 8;
+ buf[4] = uid->len;
+ md_write( md, buf, 5 );
+ }
md_write( md, uid->name, uid->len );
+ }
/* and make the signature packet */
sig = m_alloc_clear( sizeof *sig );
+ sig->version = skc->version;
+ keyid_from_skc( skc, sig->keyid );
sig->pubkey_algo = skc->pubkey_algo;
+ sig->digest_algo = digest_algo;
sig->timestamp = make_timestamp();
sig->sig_class = sigclass;
+ if( sig->version >= 4 ) {
+ build_sig_subpkt_from_sig( sig );
+ md_putc( md, sig->version );
+ }
md_putc( md, sig->sig_class );
- { u32 a = sig->timestamp;
+ if( sig->version < 4 ) {
+ u32 a = sig->timestamp;
md_putc( md, (a >> 24) & 0xff );
md_putc( md, (a >> 16) & 0xff );
md_putc( md, (a >> 8) & 0xff );
md_putc( md, a & 0xff );
}
+ else {
+ byte buf[6];
+ size_t n;
+
+ md_putc( md, sig->pubkey_algo );
+ md_putc( md, sig->digest_algo );
+ if( sig->hashed_data ) {
+ n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
+ md_write( md, sig->hashed_data, n+2 );
+ n += 6;
+ }
+ else
+ n = 6;
+ /* 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[3] = n >> 16;
+ buf[4] = n >> 8;
+ buf[5] = n;
+ md_write( md, buf, 6 );
+
+ }
md_final(md);
rc = complete_sig( sig, skc, md );