aboutsummaryrefslogtreecommitdiffstats
path: root/g10/getkey.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/getkey.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index 189ef0be1..f9f4c9f43 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -613,7 +613,7 @@ compare_name( const char *uid, size_t uidlen, const char *name, int mode )
*/
static void
-add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode )
+merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
{
PKT_public_key *pk = knode->pkt->pkt.public_key;
PKT_signature *sig;
@@ -643,9 +643,8 @@ add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode )
&& sig->keyid[1] == kid[1]
&& sig->version > 3 ) {
/* okay this is (the first) self-signature which can be used
- * fixme: Check how to handle subkey bindings
* FIXME: We should only use this if the signature is valid
- * but this is time consuming - we muts provide another
+ * but this is time consuming - we must provide another
* way to handle this
*/
const byte *p;
@@ -659,6 +658,63 @@ add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode )
/****************
+ * merge all selfsignatures with the keys.
+ */
+void
+merge_keys_and_selfsig( KBNODE keyblock )
+{
+ PKT_public_key *pk = NULL;
+ PKT_secret_key *sk = NULL;
+ PKT_signature *sig;
+ KBNODE k;
+ u32 kid[2];
+
+ for(k=keyblock; k; k = k->next ) {
+ if( k->pkt->pkttype == PKT_PUBLIC_KEY
+ || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+ pk = k->pkt->pkt.public_key; sk = NULL;
+ if( pk->version < 4 )
+ pk = NULL; /* not needed for old keys */
+ else
+ keyid_from_pk( pk, kid );
+ }
+ else if( k->pkt->pkttype == PKT_SECRET_KEY
+ || k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
+ pk = NULL; sk = k->pkt->pkt.secret_key;
+ if( sk->version < 4 )
+ sk = NULL;
+ else
+ keyid_from_sk( sk, kid );
+ }
+ else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE
+ && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
+ && sig->sig_class <= 0x13 && sig->version > 3
+ && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
+ /* okay this is (the first) self-signature which can be used
+ * FIXME: We should only use this if the signature is valid
+ * but this is time consuming - we must provide another
+ * way to handle this
+ */
+ const byte *p;
+ p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
+ if( pk ) {
+ pk->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0;
+ /* fixme: add usage etc. */
+ pk = NULL; /* use only the first self signature */
+ }
+ else {
+ sk->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0;
+ sk = NULL; /* use only the first self signature */
+ }
+ }
+ }
+}
+
+
+
+
+
+/****************
* Lookup a key by scanning all keyrings
* mode 1 = lookup by NAME (exact)
* 2 = lookup by NAME (substring)
@@ -808,12 +864,12 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
if( primary && !pk->pubkey_usage ) {
copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key,
use_namehash? namehash:NULL);
- add_stuff_from_selfsig( keyblock, keyblock );
+ merge_one_pk_and_selfsig( keyblock, keyblock );
}
else {
copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
use_namehash? namehash:NULL);
- add_stuff_from_selfsig( keyblock, k );
+ merge_one_pk_and_selfsig( keyblock, k );
}
if( ret_keyblock ) {
*ret_keyblock = keyblock;