aboutsummaryrefslogtreecommitdiffstats
path: root/g10/getkey.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/getkey.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index 5f607ec51..c8e8ea012 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -30,6 +30,7 @@
#include "iobuf.h"
#include "keydb.h"
#include "options.h"
+#include "main.h"
#define MAX_PKC_CACHE_ENTRIES 500
@@ -595,6 +596,58 @@ compare_name( const char *uid, size_t uidlen, const char *name, int mode )
}
+
+/****************
+ * Assume that knode points to a public key packet and keyblock is
+ * the entire keyblock. This function adds all relevant information from
+ * a selfsignature to the public key.
+ */
+
+static void
+add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode )
+{
+ PKT_public_cert *pkc = knode->pkt->pkt.public_cert;
+ PKT_signature *sig;
+ KBNODE k;
+ u32 kid[2];
+
+ assert( knode->pkt->pkttype == PKT_PUBLIC_CERT
+ || knode->pkt->pkttype == PKT_PUBKEY_SUBCERT );
+
+ if( pkc->version < 4 )
+ return; /* this is only needed for version >=4 packets */
+
+ /* find the selfsignature */
+ if( knode->pkt->pkttype == PKT_PUBKEY_SUBCERT ) {
+ k = find_kbnode( keyblock, PKT_PUBLIC_CERT );
+ if( !k )
+ BUG(); /* keyblock without primary key!!! */
+ keyid_from_pkc( knode->pkt->pkt.public_cert, kid );
+ }
+ else
+ keyid_from_pkc( pkc, kid );
+ for(k=keyblock; k; k = k->next ) {
+ if( k->pkt->pkttype == PKT_SIGNATURE
+ && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
+ && sig->sig_class <= 0x13
+ && sig->keyid[0] == kid[0]
+ && 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
+ * way to handle this
+ */
+ const byte *p;
+ p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
+ pkc->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0;
+ /* fixme: add usage etc. to pkc */
+ break;
+ }
+ }
+}
+
/****************
* Lookup a key by scanning all keyrings
* mode 1 = lookup by NAME (exact)
@@ -718,6 +771,7 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid,
assert( k->pkt->pkttype == PKT_PUBLIC_CERT
|| k->pkt->pkttype == PKT_PUBKEY_SUBCERT );
copy_public_cert( pkc, k->pkt->pkt.public_cert );
+ add_stuff_from_selfsig( keyblock, k );
if( ret_keyblock ) {
*ret_keyblock = keyblock;
keyblock = NULL;