~ubuntu-branches/ubuntu/jaunty/gnupg2/jaunty

« back to all changes in this revision

Viewing changes to g10/sig-check.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* sig-check.c -  Check a signature
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
 
3
 *               2003  Free Software Foundation, Inc.
 
4
 *
 
5
 * This file is part of GnuPG.
 
6
 *
 
7
 * GnuPG is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * GnuPG is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
20
 */
 
21
 
 
22
#include <config.h>
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <assert.h>
 
27
 
 
28
#include "gpg.h"
 
29
#include "util.h"
 
30
#include "packet.h"
 
31
#include "memory.h"
 
32
#include "mpi.h"
 
33
#include "keydb.h"
 
34
#include "cipher.h"
 
35
#include "main.h"
 
36
#include "status.h"
 
37
#include "i18n.h"
 
38
#include "options.h"
 
39
#include "pkglue.h"
 
40
 
 
41
struct cmp_help_context_s {
 
42
    PKT_signature *sig;
 
43
    MD_HANDLE md;
 
44
};
 
45
 
 
46
 
 
47
static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
 
48
                     int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
 
49
 
 
50
/****************
 
51
 * Check the signature which is contained in SIG.
 
52
 * The MD_HANDLE should be currently open, so that this function
 
53
 * is able to append some data, before finalizing the digest.
 
54
 */
 
55
int
 
56
signature_check( PKT_signature *sig, MD_HANDLE digest )
 
57
{
 
58
    return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
 
59
}
 
60
 
 
61
int
 
62
signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, 
 
63
                  int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
 
64
{
 
65
    PKT_public_key *pk = xcalloc (1, sizeof *pk );
 
66
    int rc=0;
 
67
 
 
68
    /* Sanity check that the md has a context for the hash that the
 
69
       sig is expecting.  This can happen if a onepass sig header does
 
70
       not match the actual sig, and also if the clearsign "Hash:"
 
71
       header is missing or does not match the actual sig. */
 
72
 
 
73
    if(!gcry_md_is_enabled (digest,sig->digest_algo)) {
 
74
        log_info(_("WARNING: signature digest conflict in message\n"));
 
75
        rc=GPG_ERR_GENERAL;
 
76
    }
 
77
    else if( get_pubkey( pk, sig->keyid ) )
 
78
        rc = GPG_ERR_NO_PUBKEY;
 
79
    else if(!pk->is_valid && !pk->is_primary)
 
80
        rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an
 
81
                                 invalid subkey */
 
82
    else {
 
83
        if (r_expiredate)
 
84
            *r_expiredate = pk->expiredate;
 
85
        rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
 
86
    }
 
87
 
 
88
    free_public_key( pk );
 
89
 
 
90
    if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
 
91
        /* This signature id works best with DLP algorithms because
 
92
         * they use a random parameter for every signature.  Instead of
 
93
         * this sig-id we could have also used the hash of the document
 
94
         * and the timestamp, but the drawback of this is, that it is
 
95
         * not possible to sign more than one identical document within
 
96
         * one second.  Some remote batch processing applications might
 
97
         * like this feature here */
 
98
        gcry_md_hd_t md;
 
99
        u32 a = sig->timestamp;
 
100
        int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
 
101
        byte *p, *buffer;
 
102
 
 
103
        gcry_md_open (&md, GCRY_MD_RMD160, 0);
 
104
        gcry_md_putc( digest, sig->pubkey_algo );
 
105
        gcry_md_putc( digest, sig->digest_algo );
 
106
        gcry_md_putc( digest, (a >> 24) & 0xff );
 
107
        gcry_md_putc( digest, (a >> 16) & 0xff );
 
108
        gcry_md_putc( digest, (a >>  8) & 0xff );
 
109
        gcry_md_putc( digest,  a        & 0xff );
 
110
        for(i=0; i < nsig; i++ ) {
 
111
            size_t n;
 
112
            unsigned char *tmp;
 
113
 
 
114
            if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i]))
 
115
                BUG();
 
116
            
 
117
            gcry_md_write (md, tmp, n);
 
118
            xfree (tmp);
 
119
        }
 
120
        gcry_md_final( md );
 
121
        p = make_radix64_string( gcry_md_read( md, 0 ), 20 );
 
122
        buffer = xmalloc ( strlen(p) + 60 );
 
123
        sprintf( buffer, "%s %s %lu",
 
124
                 p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
 
125
        write_status_text( STATUS_SIG_ID, buffer );
 
126
        xfree (buffer);
 
127
        xfree (p);
 
128
        gcry_md_close(md);
 
129
    }
 
130
 
 
131
    return rc;
 
132
}
 
133
 
 
134
 
 
135
static int
 
136
do_check_messages( PKT_public_key *pk, PKT_signature *sig,
 
137
                   int *r_expired, int *r_revoked )
 
138
{
 
139
    u32 cur_time;
 
140
 
 
141
    if (r_expired)
 
142
      *r_expired = 0;
 
143
    if (r_revoked)
 
144
      *r_revoked = 0;
 
145
    if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
 
146
        log_info(_("key %08lX: this is a PGP generated "
 
147
                   "ElGamal key which is NOT secure for signatures!\n"),
 
148
                  (ulong)keyid_from_pk(pk,NULL));
 
149
        return GPG_ERR_PUBKEY_ALGO;
 
150
    }
 
151
 
 
152
    if( pk->timestamp > sig->timestamp ) {
 
153
        ulong d = pk->timestamp - sig->timestamp;
 
154
        log_info( d==1
 
155
             ? _("public key %08lX is %lu second newer than the signature\n")
 
156
             : _("public key %08lX is %lu seconds newer than the signature\n"),
 
157
                (ulong)keyid_from_pk(pk,NULL),d );
 
158
        if( !opt.ignore_time_conflict )
 
159
            return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature */
 
160
    }
 
161
 
 
162
    cur_time = make_timestamp();
 
163
    if( pk->timestamp > cur_time ) {
 
164
        ulong d = pk->timestamp - cur_time;
 
165
        log_info( d==1 ? _("key %08lX has been created %lu second "
 
166
                           "in future (time warp or clock problem)\n")
 
167
                       : _("key %08lX has been created %lu seconds "
 
168
                           "in future (time warp or clock problem)\n"),
 
169
                       (ulong)keyid_from_pk(pk,NULL),d );
 
170
        if( !opt.ignore_time_conflict )
 
171
            return GPG_ERR_TIME_CONFLICT;
 
172
    }
 
173
 
 
174
    if( pk->expiredate && pk->expiredate < cur_time ) {
 
175
        char buf[11];
 
176
        if (opt.verbose) {
 
177
            u32 tmp_kid[2];
 
178
 
 
179
            keyid_from_pk( pk, tmp_kid );
 
180
            log_info(_("NOTE: signature key %08lX expired %s\n"),
 
181
                     (ulong)tmp_kid[1], asctimestamp( pk->expiredate ) );
 
182
        }
 
183
        /* SIGEXPIRED is deprecated.  Use KEYEXPIRED. */
 
184
        sprintf(buf,"%lu",(ulong)pk->expiredate);
 
185
        write_status_text(STATUS_KEYEXPIRED,buf);
 
186
        write_status(STATUS_SIGEXPIRED);
 
187
        if (r_expired)
 
188
          *r_expired = 1;
 
189
    }
 
190
 
 
191
    if(pk->is_revoked && r_revoked)
 
192
      *r_revoked=1;
 
193
 
 
194
    return 0;
 
195
}
 
196
 
 
197
 
 
198
static int
 
199
do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
 
200
          int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
 
201
{
 
202
    gcry_mpi_t result = NULL;
 
203
    int rc=0;
 
204
    struct cmp_help_context_s ctx;
 
205
 
 
206
    if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
 
207
        return rc;
 
208
    if( (rc=gcry_md_test_algo(sig->digest_algo)) )
 
209
        return rc;
 
210
    if( (rc=gcry_pk_test_algo(sig->pubkey_algo)) )
 
211
        return rc;
 
212
 
 
213
    /* make sure the digest algo is enabled (in case of a detached
 
214
       signature)*/
 
215
    gcry_md_enable( digest, sig->digest_algo );
 
216
 
 
217
    /* complete the digest */
 
218
    if( sig->version >= 4 )
 
219
        gcry_md_putc( digest, sig->version );
 
220
    gcry_md_putc( digest, sig->sig_class );
 
221
    if( sig->version < 4 ) {
 
222
        u32 a = sig->timestamp;
 
223
        gcry_md_putc( digest, (a >> 24) & 0xff );
 
224
        gcry_md_putc( digest, (a >> 16) & 0xff );
 
225
        gcry_md_putc( digest, (a >>     8) & 0xff );
 
226
        gcry_md_putc( digest,  a           & 0xff );
 
227
    }
 
228
    else {
 
229
        byte buf[6];
 
230
        size_t n;
 
231
        gcry_md_putc( digest, sig->pubkey_algo );
 
232
        gcry_md_putc( digest, sig->digest_algo );
 
233
        if( sig->hashed ) {
 
234
            n = sig->hashed->len;
 
235
            gcry_md_putc (digest, (n >> 8) );
 
236
            gcry_md_putc (digest,  n       );
 
237
            gcry_md_write (digest, sig->hashed->data, n);
 
238
            n += 6;
 
239
        }
 
240
        else {
 
241
          /* Two octets for the (empty) length of the hashed
 
242
             section. */
 
243
          gcry_md_putc (digest, 0);
 
244
          gcry_md_putc (digest, 0);
 
245
          n = 6;
 
246
        }
 
247
        /* add some magic */
 
248
        buf[0] = sig->version;
 
249
        buf[1] = 0xff;
 
250
        buf[2] = n >> 24;
 
251
        buf[3] = n >> 16;
 
252
        buf[4] = n >>  8;
 
253
        buf[5] = n;
 
254
        gcry_md_write( digest, buf, 6 );
 
255
    }
 
256
    gcry_md_final (digest);
 
257
 
 
258
    result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
 
259
                              mpi_get_nbits(pk->pkey[0]), 0 );
 
260
    if (!result)
 
261
        return GPG_ERR_GENERAL;
 
262
    ctx.sig = sig;
 
263
    ctx.md = digest;
 
264
    rc = pk_verify ( pk->pubkey_algo, result, sig->data, pk->pkey);
 
265
    gcry_mpi_release ( result );
 
266
    if( (opt.emulate_bugs & EMUBUG_MDENCODE)
 
267
        && gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE
 
268
        && is_ELGAMAL(pk->pubkey_algo) ) {
 
269
        /* In this case we try again because old GnuPG versions didn't encode
 
270
         * the hash right. There is no problem with DSA however  */
 
271
        result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
 
272
                              mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
 
273
        if (!result)
 
274
            rc = GPG_ERR_GENERAL;
 
275
        else {
 
276
            ctx.sig = sig;
 
277
            ctx.md = digest;
 
278
            rc = pk_verify (pk->pubkey_algo, result, sig->data, pk->pkey);
 
279
        }
 
280
    }
 
281
 
 
282
    if( !rc && sig->flags.unknown_critical ) {
 
283
      log_info(_("assuming bad signature from key %08lX "
 
284
                 "due to an unknown critical bit\n"),
 
285
               (ulong)keyid_from_pk(pk,NULL));
 
286
        rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
 
287
    }
 
288
 
 
289
    if(!rc && ret_pk)
 
290
      copy_public_key(ret_pk,pk);
 
291
 
 
292
    return rc;
 
293
}
 
294
 
 
295
 
 
296
static void
 
297
hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
 
298
{
 
299
    PKT_user_id *uid = unode->pkt->pkt.user_id;
 
300
 
 
301
    assert( unode->pkt->pkttype == PKT_USER_ID );
 
302
    if( uid->attrib_data ) {
 
303
        if( sig->version >=4 ) {
 
304
            byte buf[5];
 
305
            buf[0] = 0xd1;                   /* packet of type 17 */
 
306
            buf[1] = uid->attrib_len >> 24;  /* always use 4 length bytes */
 
307
            buf[2] = uid->attrib_len >> 16;
 
308
            buf[3] = uid->attrib_len >>  8;
 
309
            buf[4] = uid->attrib_len;
 
310
            gcry_md_write( md, buf, 5 );
 
311
        }
 
312
        gcry_md_write( md, uid->attrib_data, uid->attrib_len );
 
313
    }
 
314
    else {
 
315
        if( sig->version >=4 ) {
 
316
            byte buf[5];
 
317
            buf[0] = 0xb4;            /* indicates a userid packet */
 
318
            buf[1] = uid->len >> 24;  /* always use 4 length bytes */
 
319
            buf[2] = uid->len >> 16;
 
320
            buf[3] = uid->len >>  8;
 
321
            buf[4] = uid->len;
 
322
            gcry_md_write( md, buf, 5 );
 
323
        }
 
324
        gcry_md_write( md, uid->name, uid->len );
 
325
    }
 
326
}
 
327
 
 
328
static void
 
329
cache_sig_result ( PKT_signature *sig, int result )
 
330
{
 
331
    if ( !result ) {
 
332
        sig->flags.checked = 1;
 
333
        sig->flags.valid = 1;
 
334
    }
 
335
    else if ( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) {
 
336
        sig->flags.checked = 1;
 
337
        sig->flags.valid = 0;
 
338
    }
 
339
    else {
 
340
        sig->flags.checked = 0;
 
341
        sig->flags.valid = 0;
 
342
    }
 
343
}
 
344
 
 
345
 
 
346
/* Check the revocation keys to see if any of them have revoked our
 
347
   pk.  sig is the revocation sig.  pk is the key it is on.  This code
 
348
   will need to be modified if gpg ever becomes multi-threaded.  Note
 
349
   that this guarantees that a designated revocation sig will never be
 
350
   considered valid unless it is actually valid, as well as being
 
351
   issued by a revocation key in a valid direct signature.  Note that
 
352
   this is written so that a revoked revoker can still issue
 
353
   revocations: i.e. If A revokes B, but A is revoked, B is still
 
354
   revoked.  I'm not completely convinced this is the proper behavior,
 
355
   but it matches how PGP does it. -dms */
 
356
 
 
357
/* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not
 
358
   revoked */
 
359
int
 
360
check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
 
361
{
 
362
  static int busy=0;
 
363
  int i,rc=GPG_ERR_GENERAL;
 
364
 
 
365
  assert(IS_KEY_REV(sig));
 
366
  assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
 
367
 
 
368
  if(busy)
 
369
    {
 
370
      /* return -1 (i.e. not revoked), but mark the pk as uncacheable
 
371
         as we don't really know its revocation status until it is
 
372
         checked directly. */
 
373
 
 
374
      pk->dont_cache=1;
 
375
      return rc;
 
376
    }
 
377
 
 
378
  busy=1;
 
379
 
 
380
  /*  printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1],
 
381
      (ulong)sig->keyid[1]); */
 
382
 
 
383
  /* is the issuer of the sig one of our revokers? */
 
384
  if( !pk->revkey && pk->numrevkeys )
 
385
     BUG();
 
386
  else
 
387
      for(i=0;i<pk->numrevkeys;i++)
 
388
        {
 
389
          u32 keyid[2];
 
390
    
 
391
          keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid);
 
392
    
 
393
          if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1])
 
394
            {
 
395
              gcry_md_hd_t md;
 
396
    
 
397
              gcry_md_open (&md, sig->digest_algo,0);
 
398
              hash_public_key(md,pk);
 
399
              rc=signature_check(sig,md);
 
400
              cache_sig_result(sig,rc);
 
401
              break;
 
402
            }
 
403
        }
 
404
 
 
405
  busy=0;
 
406
 
 
407
  return rc;
 
408
 
409
 
 
410
/****************
 
411
 * check the signature pointed to by NODE. This is a key signature.
 
412
 * If the function detects a self-signature, it uses the PK from
 
413
 * ROOT and does not read any public key.
 
414
 */
 
415
int
 
416
check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
 
417
{
 
418
    return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL);
 
419
}
 
420
 
 
421
/* If check_pk is set, then use it to check the signature in node
 
422
   rather than getting it from root or the keydb.  If ret_pk is set,
 
423
   fill in the public key that was used to verify the signature.
 
424
   ret_pk is only meaningful when the verification was successful. */
 
425
/* TODO: add r_revoked here as well.  It has the same problems as
 
426
   r_expiredate and r_expired and the cache. */
 
427
int
 
428
check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
 
429
                      PKT_public_key *ret_pk, int *is_selfsig,
 
430
                      u32 *r_expiredate, int *r_expired )
 
431
{
 
432
    MD_HANDLE md;
 
433
    PKT_public_key *pk;
 
434
    PKT_signature *sig;
 
435
    int algo;
 
436
    int rc;
 
437
 
 
438
    if( is_selfsig )
 
439
        *is_selfsig = 0;
 
440
    if( r_expiredate )
 
441
        *r_expiredate = 0;
 
442
    if( r_expired )
 
443
        *r_expired = 0;
 
444
    assert( node->pkt->pkttype == PKT_SIGNATURE );
 
445
    assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
 
446
 
 
447
    pk = root->pkt->pkt.public_key;
 
448
    sig = node->pkt->pkt.signature;
 
449
    algo = sig->digest_algo;
 
450
 
 
451
    /* check whether we have cached the result of a previous signature check.*/
 
452
    if ( !opt.no_sig_cache ) {
 
453
        if (sig->flags.checked) { /*cached status available*/
 
454
            if( is_selfsig ) {  
 
455
                u32 keyid[2];   
 
456
 
 
457
                keyid_from_pk( pk, keyid );
 
458
                if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
 
459
                    *is_selfsig = 1;
 
460
            }
 
461
            /* BUG: This is wrong for non-self-sigs. Needs to be the
 
462
               actual pk */
 
463
            if((rc=do_check_messages(pk,sig,r_expired,NULL)))
 
464
              return rc;
 
465
            return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE);
 
466
        }
 
467
    }
 
468
 
 
469
    if( (rc=gcry_md_test_algo(algo)) )
 
470
      return rc;
 
471
 
 
472
    if( sig->sig_class == 0x20 ) { /* key revocation */
 
473
        u32 keyid[2];   
 
474
        keyid_from_pk( pk, keyid );
 
475
 
 
476
        /* is it a designated revoker? */
 
477
        if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1])
 
478
          rc=check_revocation_keys(pk,sig);
 
479
        else
 
480
          {
 
481
            gcry_md_open (&md, algo, 0 );
 
482
            hash_public_key( md, pk );
 
483
            rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
 
484
            cache_sig_result ( sig, rc );
 
485
            gcry_md_close(md);
 
486
          }
 
487
    }
 
488
    else if( sig->sig_class == 0x28 ) { /* subkey revocation */
 
489
        KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
 
490
 
 
491
        if( snode ) {
 
492
            gcry_md_open (&md, algo, 0 );
 
493
            hash_public_key( md, pk );
 
494
            hash_public_key( md, snode->pkt->pkt.public_key );
 
495
            rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
 
496
            cache_sig_result ( sig, rc );
 
497
            gcry_md_close(md);
 
498
        }
 
499
        else {
 
500
            if (opt.verbose)
 
501
                log_info (_("key %08lX: no subkey for subkey "
 
502
                            "revocation signature\n"),
 
503
                          (ulong)keyid_from_pk (pk, NULL));
 
504
            rc = GPG_ERR_SIG_CLASS;
 
505
        }
 
506
    }
 
507
    else if( sig->sig_class == 0x18 ) { /* key binding */
 
508
        KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
 
509
 
 
510
        if( snode ) {
 
511
            if( is_selfsig ) {  /* does this make sense????? */
 
512
                u32 keyid[2];   /* it should always be a selfsig */
 
513
 
 
514
                keyid_from_pk( pk, keyid );
 
515
                if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
 
516
                    *is_selfsig = 1;
 
517
            }
 
518
            gcry_md_open (&md, algo, 0 );
 
519
            hash_public_key( md, pk );
 
520
            hash_public_key( md, snode->pkt->pkt.public_key );
 
521
            rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
 
522
            cache_sig_result ( sig, rc );
 
523
            gcry_md_close(md);
 
524
        }
 
525
        else {
 
526
            if (opt.verbose)
 
527
                log_info(_("key %08lX: no subkey for subkey "
 
528
                           "binding signature\n"),
 
529
                         (ulong)keyid_from_pk (pk, NULL));
 
530
            rc = GPG_ERR_SIG_CLASS;
 
531
        }
 
532
    }
 
533
    else if( sig->sig_class == 0x1f ) { /* direct key signature */
 
534
        gcry_md_open (&md, algo, 0 );
 
535
        hash_public_key( md, pk );
 
536
        rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
 
537
        cache_sig_result ( sig, rc );
 
538
        gcry_md_close(md);
 
539
    }
 
540
    else { /* all other classes */
 
541
        KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
 
542
 
 
543
        if( unode ) {
 
544
            u32 keyid[2];
 
545
 
 
546
            keyid_from_pk( pk, keyid );
 
547
            gcry_md_open (&md, algo, 0 );
 
548
            hash_public_key( md, pk );
 
549
            hash_uid_node( unode, md, sig );
 
550
            if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
 
551
              {
 
552
                if( is_selfsig )
 
553
                  *is_selfsig = 1;
 
554
                rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
 
555
              }
 
556
            else if (check_pk)
 
557
              rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk);
 
558
            else
 
559
              rc = signature_check2( sig, md, r_expiredate, r_expired,
 
560
                                     NULL, ret_pk);
 
561
 
 
562
            cache_sig_result ( sig, rc );
 
563
            gcry_md_close(md);
 
564
        }
 
565
        else {
 
566
            if (!opt.quiet)
 
567
                log_info ("key %08lX: no user ID for key signature packet "
 
568
                          "of class %02x\n",
 
569
                          (ulong)keyid_from_pk (pk, NULL), sig->sig_class );
 
570
            rc = GPG_ERR_SIG_CLASS;
 
571
        }
 
572
    }
 
573
 
 
574
    return rc;
 
575
}