~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to g10/pkclist.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
/* pkclist.c
 
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 <errno.h>
 
27
#include <assert.h>
 
28
 
 
29
#include "options.h"
 
30
#include "packet.h"
 
31
#include "errors.h"
 
32
#include "keydb.h"
 
33
#include "memory.h"
 
34
#include "util.h"
 
35
#include "main.h"
 
36
#include "trustdb.h"
 
37
#include "ttyio.h"
 
38
#include "status.h"
 
39
#include "photoid.h"
 
40
#include "i18n.h"
 
41
 
 
42
 
 
43
#define CONTROL_D ('D' - 'A' + 1)
 
44
 
 
45
 
 
46
/****************
 
47
 * Show the revocation reason as it is stored with the given signature
 
48
 */
 
49
static void
 
50
do_show_revocation_reason( PKT_signature *sig )
 
51
{
 
52
    size_t n, nn;
 
53
    const byte *p, *pp;
 
54
    int seq = 0;
 
55
    const char *text;
 
56
 
 
57
    while( (p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REVOC_REASON,
 
58
                                 &n, &seq, NULL )) ) {
 
59
        if( !n )
 
60
            continue; /* invalid - just skip it */
 
61
 
 
62
        if( *p == 0 )
 
63
            text = _("No reason specified");
 
64
        else if( *p == 0x01 )
 
65
            text = _("Key is superseded");
 
66
        else if( *p == 0x02 )
 
67
            text = _("Key has been compromised");
 
68
        else if( *p == 0x03 )
 
69
            text = _("Key is no longer used");
 
70
        else if( *p == 0x20 )
 
71
            text = _("User ID is no longer valid");
 
72
        else
 
73
            text = NULL;
 
74
 
 
75
        log_info( _("reason for revocation: ") );
 
76
        if( text )
 
77
            fputs( text, log_get_stream () );
 
78
        else
 
79
            fprintf( log_get_stream (), "code=%02x", *p );
 
80
        putc( '\n', log_get_stream () );
 
81
        n--; p++;
 
82
        pp = NULL;
 
83
        do {
 
84
            /* We don't want any empty lines, so skip them */
 
85
            while( n && *p == '\n' ) {
 
86
                p++;
 
87
                n--;
 
88
            }
 
89
            if( n ) {
 
90
                pp = memchr( p, '\n', n );
 
91
                nn = pp? pp - p : n;
 
92
                log_info( _("revocation comment: ") );
 
93
                print_string( log_get_stream(), p, nn, 0 );
 
94
                putc( '\n', log_get_stream() );
 
95
                p += nn; n -= nn;
 
96
            }
 
97
        } while( pp );
 
98
    }
 
99
}
 
100
 
 
101
/* Mode 0: try and find the revocation based on the pk (i.e. check
 
102
   subkeys, etc.)  Mode 1: use only the revocation on the main pk */
 
103
 
 
104
void
 
105
show_revocation_reason( PKT_public_key *pk, int mode )
 
106
{
 
107
    /* Hmmm, this is not so easy becuase we have to duplicate the code
 
108
     * used in the trustbd to calculate the keyflags.  We need to find
 
109
     * a clean way to check revocation certificates on keys and
 
110
     * signatures.  And there should be no duplicate code.  Because we
 
111
     * enter this function only when the trustdb told us that we have
 
112
     * a revoked key, we could simply look for a revocation cert and
 
113
     * display this one, when there is only one. Let's try to do this
 
114
     * until we have a better solution.  */
 
115
    KBNODE node, keyblock = NULL;
 
116
    byte fingerprint[MAX_FINGERPRINT_LEN];
 
117
    size_t fingerlen;
 
118
    int rc;
 
119
 
 
120
    /* get the keyblock */
 
121
    fingerprint_from_pk( pk, fingerprint, &fingerlen );
 
122
    rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
 
123
    if( rc ) { /* that should never happen */
 
124
        log_debug( "failed to get the keyblock\n");
 
125
        return;
 
126
    }
 
127
 
 
128
    for( node=keyblock; node; node = node->next ) {
 
129
        if( (mode && node->pkt->pkttype == PKT_PUBLIC_KEY) ||
 
130
          ( ( node->pkt->pkttype == PKT_PUBLIC_KEY
 
131
              || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
 
132
            && !cmp_public_keys( node->pkt->pkt.public_key, pk ) ) )
 
133
            break;
 
134
    }
 
135
    if( !node ) {
 
136
        log_debug("Oops, PK not in keyblock\n");
 
137
        release_kbnode( keyblock );
 
138
        return;
 
139
    }
 
140
    /* now find the revocation certificate */
 
141
    for( node = node->next; node ; node = node->next ) {
 
142
        if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
 
143
            break;
 
144
        if( node->pkt->pkttype == PKT_SIGNATURE
 
145
            && (node->pkt->pkt.signature->sig_class == 0x20
 
146
                || node->pkt->pkt.signature->sig_class == 0x28 ) ) {
 
147
                /* FIXME: we should check the signature here */
 
148
                do_show_revocation_reason ( node->pkt->pkt.signature );
 
149
                break;
 
150
        }
 
151
    }
 
152
 
 
153
    /* We didn't find it, so check if the whole key is revoked */
 
154
    if(!node && !mode)
 
155
      show_revocation_reason(pk,1);
 
156
 
 
157
    release_kbnode( keyblock );
 
158
}
 
159
 
 
160
 
 
161
static void
 
162
show_paths (const PKT_public_key *pk, int only_first )
 
163
{
 
164
    log_debug("not yet implemented\n");
 
165
#if 0    
 
166
    void *context = NULL;
 
167
    unsigned otrust, validity;
 
168
    int last_level, level;
 
169
 
 
170
    last_level = 0;
 
171
    while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
 
172
        char *p;
 
173
        int c, rc;
 
174
        size_t n;
 
175
        u32 keyid[2];
 
176
        PKT_public_key *pk ;
 
177
 
 
178
        if( level < last_level && only_first )
 
179
            break;
 
180
        last_level = level;
 
181
 
 
182
        rc = keyid_from_lid( lid, keyid );
 
183
 
 
184
        if( rc ) {
 
185
            log_error("ooops: can't get keyid for lid %lu\n", lid);
 
186
            return;
 
187
        }
 
188
 
 
189
        pk = xcalloc (1, sizeof *pk );
 
190
        rc = get_pubkey( pk, keyid );
 
191
        if( rc ) {
 
192
            log_error("key %08lX: public key not found: %s\n",
 
193
                                    (ulong)keyid[1], gpg_strerror (rc) );
 
194
            return;
 
195
        }
 
196
 
 
197
        tty_printf("%*s%4u%c/%08lX.%lu %s \"",
 
198
                  level*2, "",
 
199
                  nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
 
200
                  (ulong)keyid[1], lid, datestr_from_pk( pk ) );
 
201
 
 
202
        c = trust_letter(otrust);
 
203
        if( c )
 
204
            putchar( c );
 
205
        else
 
206
            printf( "%02x", otrust );
 
207
        putchar('/');
 
208
        c = trust_letter(validity);
 
209
        if( c )
 
210
            putchar( c );
 
211
        else
 
212
            printf( "%02x", validity );
 
213
        putchar(' ');
 
214
 
 
215
        p = get_user_id( keyid, &n );
 
216
        tty_print_utf8_string( p, n ),
 
217
        xfree (p);
 
218
        tty_printf("\"\n");
 
219
        free_public_key( pk );
 
220
    }
 
221
    enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
 
222
#endif
 
223
    tty_printf("\n");
 
224
}
 
225
 
 
226
 
 
227
 
 
228
 
 
229
/****************
 
230
 * mode: 0 = standard
 
231
 *       1 = Without key info and additional menu option 'm'
 
232
 *           this does also add an option to set the key to ultimately trusted.
 
233
 * Returns: 
 
234
 *      -2 = nothing changed - caller should show some additional info
 
235
 *      -1 = quit operation
 
236
 *       0 = nothing changed
 
237
 *       1 = new ownertrust now in new_trust
 
238
 */
 
239
static int
 
240
do_edit_ownertrust (PKT_public_key *pk, int mode,
 
241
                    unsigned *new_trust, int defer_help )
 
242
{
 
243
  char *p;
 
244
  size_t n;
 
245
  u32 keyid[2];
 
246
  int changed=0;
 
247
  int quit=0;
 
248
  int show=0;
 
249
  int min_num;
 
250
  int did_help=defer_help;
 
251
  unsigned int minimum=get_min_ownertrust(pk);
 
252
 
 
253
  switch(minimum)
 
254
    {
 
255
    default:              min_num=0; break;
 
256
    case TRUST_UNDEFINED: min_num=1; break;
 
257
    case TRUST_NEVER:     min_num=2; break;
 
258
    case TRUST_MARGINAL:  min_num=3; break;
 
259
    case TRUST_FULLY:     min_num=4; break;
 
260
    }
 
261
 
 
262
  keyid_from_pk (pk, keyid);
 
263
  for(;;) {
 
264
    /* a string with valid answers */
 
265
    const char *ans = _("iImMqQsS");
 
266
 
 
267
    if( !did_help ) 
 
268
      {
 
269
        if( !mode ) 
 
270
          {
 
271
            KBNODE keyblock, un;
 
272
 
 
273
            tty_printf(_("No trust value assigned to:\n"
 
274
                         "%4u%c/%08lX %s \""),
 
275
                       nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
 
276
                       (ulong)keyid[1], datestr_from_pk( pk ) );
 
277
            p = get_user_id( keyid, &n );
 
278
            tty_print_utf8_string( p, n ),
 
279
              xfree (p);
 
280
            tty_printf("\"\n");
 
281
 
 
282
            keyblock = get_pubkeyblock (keyid);
 
283
            if (!keyblock)
 
284
                BUG ();
 
285
            for (un=keyblock; un; un = un->next) {
 
286
                if (un->pkt->pkttype != PKT_USER_ID )
 
287
                    continue;
 
288
                if (un->pkt->pkt.user_id->is_revoked )
 
289
                    continue;
 
290
                if (un->pkt->pkt.user_id->is_expired )
 
291
                    continue;
 
292
                /* Only skip textual primaries */
 
293
                if (un->pkt->pkt.user_id->is_primary &&
 
294
                    !un->pkt->pkt.user_id->attrib_data )
 
295
                    continue;
 
296
                
 
297
                if((opt.verify_options&VERIFY_SHOW_PHOTOS)
 
298
                   && un->pkt->pkt.user_id->attrib_data)
 
299
                    show_photos(un->pkt->pkt.user_id->attribs,
 
300
                                un->pkt->pkt.user_id->numattribs,pk,NULL);
 
301
                
 
302
                tty_printf ("      %s", _("                aka \""));
 
303
                tty_print_utf8_string (un->pkt->pkt.user_id->name,
 
304
                                       un->pkt->pkt.user_id->len );
 
305
                tty_printf("\"\n");
 
306
            }
 
307
        
 
308
            print_fingerprint (pk, NULL, 2);
 
309
            tty_printf("\n");
 
310
          }
 
311
        /* This string also used in keyedit.c:sign_uids */
 
312
        tty_printf (_(
 
313
                     "Please decide how far you trust this user to correctly\n"
 
314
                     "verify other users' keys (by looking at passports,\n"
 
315
                     "checking fingerprints from different sources...)?\n\n"));
 
316
        if(min_num<=1)
 
317
          tty_printf (_(" %d = I don't know\n"), 1);
 
318
        if(min_num<=2)
 
319
          tty_printf (_(" %d = I do NOT trust\n"), 2);
 
320
        if(min_num<=3)
 
321
          tty_printf (_(" %d = I trust marginally\n"), 3);
 
322
        if(min_num<=4)
 
323
          tty_printf (_(" %d = I trust fully\n"), 4);
 
324
        if (mode)
 
325
          tty_printf (_(" %d = I trust ultimately\n"), 5);
 
326
#if 0
 
327
        /* not yet implemented */
 
328
        tty_printf (_(" i = please show me more information\n") );
 
329
#endif
 
330
        if( mode )
 
331
          tty_printf(_(" m = back to the main menu\n"));
 
332
        else
 
333
          {
 
334
            tty_printf(_(" s = skip this key\n"));
 
335
            tty_printf(_(" q = quit\n"));
 
336
          }
 
337
        tty_printf("\n");
 
338
        if(minimum)
 
339
          tty_printf(_("The minimum trust level for this key is: %s\n\n"),
 
340
                     trust_value_to_string(minimum));
 
341
        did_help = 1;
 
342
      }
 
343
    if( strlen(ans) != 8 )
 
344
      BUG();
 
345
    p = cpr_get("edit_ownertrust.value",_("Your decision? "));
 
346
    trim_spaces(p);
 
347
    cpr_kill_prompt();
 
348
    if( !*p )
 
349
      did_help = 0;
 
350
    else if( *p && p[1] )
 
351
      ;
 
352
    else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) ) 
 
353
      {
 
354
        unsigned int trust;
 
355
        switch( *p )
 
356
          {
 
357
          case '1': trust = TRUST_UNDEFINED; break;
 
358
          case '2': trust = TRUST_NEVER    ; break;
 
359
          case '3': trust = TRUST_MARGINAL ; break;
 
360
          case '4': trust = TRUST_FULLY    ; break;
 
361
          case '5': trust = TRUST_ULTIMATE ; break;
 
362
          default: BUG();
 
363
          }
 
364
        if (trust == TRUST_ULTIMATE
 
365
            && !cpr_get_answer_is_yes ("edit_ownertrust.set_ultimate.okay",
 
366
                                       _("Do you really want to set this key"
 
367
                                         " to ultimate trust? ")))
 
368
          ; /* no */
 
369
        else
 
370
          {
 
371
            *new_trust = trust;
 
372
            changed = 1;
 
373
            break;
 
374
          }
 
375
      }
 
376
#if 0
 
377
    /* not yet implemented */
 
378
    else if( *p == ans[0] || *p == ans[1] ) 
 
379
      {
 
380
        tty_printf(_("Certificates leading to an ultimately trusted key:\n"));
 
381
        show = 1;
 
382
        break;
 
383
      }
 
384
#endif
 
385
    else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) 
 
386
      {
 
387
        break ; /* back to the menu */
 
388
      }
 
389
    else if( !mode && (*p == ans[6] || *p == ans[7] ) )
 
390
      {
 
391
        break; /* skip */
 
392
      }
 
393
    else if( !mode && (*p == ans[4] || *p == ans[5] ) )
 
394
      {
 
395
        quit = 1;
 
396
        break ; /* back to the menu */
 
397
      }
 
398
    xfree (p); p = NULL;
 
399
  }
 
400
  xfree (p);
 
401
  return show? -2: quit? -1 : changed;
 
402
}
 
403
 
 
404
/* 
 
405
 * Display a menu to change the ownertrust of the key PK (which should
 
406
 * be a primary key).  
 
407
 * For mode values see do_edit_ownertrust ()
 
408
 */
 
409
int
 
410
edit_ownertrust (PKT_public_key *pk, int mode )
 
411
{
 
412
  unsigned int trust;
 
413
  int no_help = 0;
 
414
 
 
415
  for(;;)
 
416
    {
 
417
      switch ( do_edit_ownertrust (pk, mode, &trust, no_help ) )
 
418
        {
 
419
        case -1: /* quit */
 
420
          return -1;
 
421
        case -2: /* show info */
 
422
          show_paths(pk, 1);
 
423
          no_help = 1;
 
424
          break;
 
425
        case 1: /* trust value set */
 
426
          trust &= ~TRUST_FLAG_DISABLED;
 
427
          trust |= get_ownertrust (pk) & TRUST_FLAG_DISABLED;
 
428
          update_ownertrust (pk, trust );
 
429
          return 1;
 
430
        default:
 
431
          return 0;
 
432
        }
 
433
    }
 
434
}
 
435
 
 
436
 
 
437
/****************
 
438
 * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
 
439
 * Returns: true if we trust.
 
440
 */
 
441
static int
 
442
do_we_trust( PKT_public_key *pk, unsigned int *trustlevel )
 
443
{
 
444
    unsigned int trustmask = 0;
 
445
 
 
446
    /* FIXME: get_pubkey_byname already checks the validity and won't
 
447
     * return keys which are either expired or revoked - so these
 
448
     * question here won't get triggered.  We have to find a solution
 
449
     * for this.  It might make sense to have a function in getkey.c
 
450
     * which does only the basic checks and returns even revoked and
 
451
     * expired keys.  This fnction could then also returhn a list of
 
452
     * keys if the speicified name is ambiguous
 
453
     */
 
454
    if( (*trustlevel & TRUST_FLAG_REVOKED) ) {
 
455
        log_info(_("key %08lX: key has been revoked!\n"),
 
456
                                        (ulong)keyid_from_pk( pk, NULL) );
 
457
        show_revocation_reason( pk, 0 );
 
458
        if( opt.batch )
 
459
          return 0; /* no */
 
460
 
 
461
        if( !cpr_get_answer_is_yes("revoked_key.override",
 
462
                                    _("Use this key anyway? ")) )
 
463
          return 0; /* no */
 
464
        trustmask |= TRUST_FLAG_REVOKED;
 
465
    }
 
466
    if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
 
467
        log_info(_("key %08lX: subkey has been revoked!\n"),
 
468
                                        (ulong)keyid_from_pk( pk, NULL) );
 
469
        show_revocation_reason( pk, 0 );
 
470
        if( opt.batch )
 
471
            return 0;
 
472
 
 
473
        if( !cpr_get_answer_is_yes("revoked_key.override",
 
474
                                    _("Use this key anyway? ")) )
 
475
            return 0;
 
476
        trustmask |= TRUST_FLAG_SUB_REVOKED;
 
477
    }
 
478
    *trustlevel &= ~trustmask;
 
479
 
 
480
    if( opt.trust_model==TM_ALWAYS ) {
 
481
        if( opt.verbose )
 
482
            log_info("No trust check due to --trust-model always option\n");
 
483
        return 1;
 
484
    }
 
485
 
 
486
    switch( (*trustlevel & TRUST_MASK) ) {
 
487
      case TRUST_EXPIRED:
 
488
        log_info(_("%08lX: key has expired\n"),
 
489
                                    (ulong)keyid_from_pk( pk, NULL) );
 
490
        return 0; /* no */
 
491
 
 
492
      default:
 
493
         log_error ("invalid trustlevel %u returned from validation layer\n",
 
494
                    *trustlevel);
 
495
         /* fall thru */
 
496
      case TRUST_UNKNOWN: 
 
497
      case TRUST_UNDEFINED:
 
498
        log_info(_("%08lX: There is no assurance this key belongs "
 
499
                   "to the named user\n"),(ulong)keyid_from_pk( pk, NULL) );
 
500
        return 0; /* no */
 
501
 
 
502
        /* No way to get here? */
 
503
      case TRUST_NEVER:
 
504
        log_info(_("%08lX: We do NOT trust this key\n"),
 
505
                                        (ulong)keyid_from_pk( pk, NULL) );
 
506
        return 0; /* no */
 
507
 
 
508
      case TRUST_MARGINAL:
 
509
        log_info(_("%08lX: There is limited assurance this key belongs "
 
510
                   "to the named user\n"),(ulong)keyid_from_pk(pk,NULL));
 
511
        return 1; /* yes */
 
512
 
 
513
      case TRUST_FULLY:
 
514
        if( opt.verbose )
 
515
            log_info(_("This key probably belongs to the named user\n"));
 
516
        return 1; /* yes */
 
517
 
 
518
      case TRUST_ULTIMATE:
 
519
        if( opt.verbose )
 
520
            log_info(_("This key belongs to us\n"));
 
521
        return 1; /* yes */
 
522
    }
 
523
 
 
524
    return 1; /* yes */
 
525
}
 
526
 
 
527
 
 
528
 
 
529
/****************
 
530
 * wrapper around do_we_trust, so we can ask whether to use the
 
531
 * key anyway.
 
532
 */
 
533
static int
 
534
do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel )
 
535
{
 
536
    int rc;
 
537
 
 
538
    rc = do_we_trust( pk, &trustlevel );
 
539
 
 
540
    if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
 
541
        return 0;
 
542
    if( (trustlevel & TRUST_FLAG_SUB_REVOKED) && !rc )
 
543
        return 0;
 
544
 
 
545
    if( !opt.batch && !rc ) {
 
546
        u32 keyid[2];
 
547
 
 
548
        keyid_from_pk( pk, keyid);
 
549
        tty_printf( "%4u%c/%08lX %s \"",
 
550
                  nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
 
551
                  (ulong)keyid[1], datestr_from_pk( pk ) );
 
552
        /* If the pk was chosen by a particular user ID, this is the
 
553
           one to ask about. */
 
554
        if(pk->user_id)
 
555
          tty_print_utf8_string(pk->user_id->name,pk->user_id->len);
 
556
        else
 
557
          {
 
558
            size_t n;
 
559
            char *p = get_user_id( keyid, &n );
 
560
            tty_print_utf8_string( p, n );
 
561
            xfree (p);
 
562
          }
 
563
        tty_printf("\"\n");
 
564
        print_fingerprint (pk, NULL, 2);
 
565
        tty_printf("\n");
 
566
 
 
567
        tty_printf(_(
 
568
"It is NOT certain that the key belongs to the person named\n"
 
569
"in the user ID.  If you *really* know what you are doing,\n"
 
570
"you may answer the next question with yes\n\n"));
 
571
 
 
572
        if( cpr_get_answer_is_yes("untrusted_key.override",
 
573
                                  _("Use this key anyway? "))  )
 
574
            rc = 1;
 
575
 
 
576
        /* Hmmm: Should we set a flag to tell the user about
 
577
         *       his decision the next time he encrypts for this recipient?
 
578
         */
 
579
    }
 
580
    else if( opt.trust_model==TM_ALWAYS && !rc ) {
 
581
        if( !opt.quiet )
 
582
            log_info(_("WARNING: Using untrusted key!\n"));
 
583
        rc = 1;
 
584
    }
 
585
    return rc;
 
586
}
 
587
 
 
588
 
 
589
 
 
590
/****************
 
591
 * Check whether we can trust this signature.
 
592
 * Returns: Error if we shall not trust this signatures.
 
593
 */
 
594
int
 
595
check_signatures_trust( PKT_signature *sig )
 
596
{
 
597
  PKT_public_key *pk = xcalloc (1, sizeof *pk );
 
598
  unsigned int trustlevel;
 
599
  int rc=0;
 
600
 
 
601
  rc = get_pubkey( pk, sig->keyid );
 
602
  if (rc) 
 
603
    { /* this should not happen */
 
604
      log_error("Ooops; the key vanished  - can't check the trust\n");
 
605
      rc = GPG_ERR_NO_PUBKEY;
 
606
      goto leave;
 
607
    }
 
608
 
 
609
  if ( opt.trust_model==TM_ALWAYS )
 
610
    {
 
611
      if( !opt.quiet )
 
612
        log_info(_("WARNING: Using untrusted key!\n"));
 
613
      if (opt.with_fingerprint)
 
614
        print_fingerprint (pk, NULL, 1);
 
615
      goto leave;
 
616
    }
 
617
 
 
618
  trustlevel = get_validity (pk, NULL);
 
619
 
 
620
  if ( (trustlevel & TRUST_FLAG_REVOKED) ) 
 
621
    {
 
622
      write_status( STATUS_KEYREVOKED );
 
623
      log_info(_("WARNING: This key has been revoked by its owner!\n"));
 
624
      log_info(_("         This could mean that the signature is forgery.\n"));
 
625
      show_revocation_reason( pk, 0 );
 
626
    }
 
627
  else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) 
 
628
    {
 
629
      write_status( STATUS_KEYREVOKED );
 
630
      log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
 
631
      show_revocation_reason( pk, 0 );
 
632
    }
 
633
  
 
634
  if ((trustlevel & TRUST_FLAG_DISABLED))
 
635
    log_info (_("Note: This key has been disabled.\n"));
 
636
 
 
637
  switch ( (trustlevel & TRUST_MASK) ) 
 
638
    {
 
639
    case TRUST_EXPIRED:
 
640
      log_info(_("Note: This key has expired!\n"));
 
641
      print_fingerprint (pk, NULL, 1);
 
642
      break;
 
643
        
 
644
    default:
 
645
      log_error ("invalid trustlevel %u returned from validation layer\n",
 
646
                 trustlevel);
 
647
      /* fall thru */
 
648
    case TRUST_UNKNOWN: 
 
649
    case TRUST_UNDEFINED:
 
650
      write_status( STATUS_TRUST_UNDEFINED );
 
651
      log_info(_("WARNING: This key is not certified with"
 
652
                 " a trusted signature!\n"));
 
653
      log_info(_("         There is no indication that the "
 
654
                 "signature belongs to the owner.\n" ));
 
655
      print_fingerprint (pk, NULL, 1);
 
656
      break;
 
657
 
 
658
    case TRUST_NEVER:
 
659
      /* currently we won't get that status */
 
660
      write_status( STATUS_TRUST_NEVER );
 
661
      log_info(_("WARNING: We do NOT trust this key!\n"));
 
662
      log_info(_("         The signature is probably a FORGERY.\n"));
 
663
      if (opt.with_fingerprint)
 
664
        print_fingerprint (pk, NULL, 1);
 
665
      rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
 
666
      break;
 
667
 
 
668
    case TRUST_MARGINAL:
 
669
      write_status( STATUS_TRUST_MARGINAL );
 
670
      log_info(_("WARNING: This key is not certified with"
 
671
                 " sufficiently trusted signatures!\n"));
 
672
      log_info(_("         It is not certain that the"
 
673
                 " signature belongs to the owner.\n" ));
 
674
      print_fingerprint (pk, NULL, 1);
 
675
      break;
 
676
 
 
677
    case TRUST_FULLY:
 
678
      write_status( STATUS_TRUST_FULLY );
 
679
      if (opt.with_fingerprint)
 
680
        print_fingerprint (pk, NULL, 1);
 
681
      break;
 
682
 
 
683
    case TRUST_ULTIMATE:
 
684
      write_status( STATUS_TRUST_ULTIMATE );
 
685
      if (opt.with_fingerprint)
 
686
        print_fingerprint (pk, NULL, 1);
 
687
      break;
 
688
    }
 
689
 
 
690
 leave:
 
691
  free_public_key( pk );
 
692
  return rc;
 
693
}
 
694
 
 
695
 
 
696
void
 
697
release_pk_list( PK_LIST pk_list )
 
698
{
 
699
    PK_LIST pk_rover;
 
700
 
 
701
    for( ; pk_list; pk_list = pk_rover ) {
 
702
        pk_rover = pk_list->next;
 
703
        free_public_key( pk_list->pk );
 
704
        xfree ( pk_list );
 
705
    }
 
706
}
 
707
 
 
708
 
 
709
static int
 
710
key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
 
711
{
 
712
    for( ; pk_list; pk_list = pk_list->next)
 
713
        if (cmp_public_keys(pk_list->pk, pk) == 0)
 
714
            return 0;
 
715
 
 
716
    return -1;
 
717
}
 
718
 
 
719
 
 
720
/****************
 
721
 * Return a malloced string with a default reciepient if there is any
 
722
 */
 
723
static char *
 
724
default_recipient(void)
 
725
{
 
726
    PKT_secret_key *sk;
 
727
    byte fpr[MAX_FINGERPRINT_LEN+1];
 
728
    size_t n;
 
729
    char *p;
 
730
    int i;
 
731
 
 
732
    if( opt.def_recipient )
 
733
        return xstrdup ( opt.def_recipient );
 
734
    if( !opt.def_recipient_self )
 
735
        return NULL;
 
736
    sk = xcalloc (1, sizeof *sk );
 
737
    i = get_seckey_byname( sk, NULL, 0 );
 
738
    if( i ) {
 
739
        free_secret_key( sk );
 
740
        return NULL;
 
741
    }
 
742
    n = MAX_FINGERPRINT_LEN;
 
743
    fingerprint_from_sk( sk, fpr, &n );
 
744
    free_secret_key( sk );
 
745
    p = xmalloc ( 2*n+3 );
 
746
    *p++ = '0';
 
747
    *p++ = 'x';
 
748
    for(i=0; i < n; i++ )
 
749
        sprintf( p+2*i, "%02X", fpr[i] );
 
750
    p -= 2;
 
751
    return p;
 
752
}
 
753
 
 
754
static int
 
755
expand_id(const char *id,STRLIST *into,unsigned int flags)
 
756
{
 
757
  struct groupitem *groups;
 
758
  int count=0;
 
759
 
 
760
  for(groups=opt.grouplist;groups;groups=groups->next)
 
761
    {
 
762
      /* need strcasecmp() here, as this should be localized */
 
763
      if(strcasecmp(groups->name,id)==0)
 
764
        {
 
765
          STRLIST each,sl;
 
766
 
 
767
          /* this maintains the current utf8-ness */
 
768
          for(each=groups->values;each;each=each->next)
 
769
            {
 
770
              sl=add_to_strlist(into,each->d);
 
771
              sl->flags=flags;
 
772
              count++;
 
773
            }
 
774
 
 
775
          break;
 
776
        }
 
777
    }
 
778
 
 
779
  return count;
 
780
}
 
781
 
 
782
/* For simplicity, and to avoid potential loops, we only expand once -
 
783
   you can't make an alias that points to an alias. */
 
784
static STRLIST
 
785
expand_group(STRLIST input)
 
786
{
 
787
  STRLIST sl,output=NULL,rover;
 
788
 
 
789
  for(rover=input;rover;rover=rover->next)
 
790
    if(expand_id(rover->d,&output,rover->flags)==0)
 
791
      {
 
792
        /* Didn't find any groups, so use the existing string */
 
793
        sl=add_to_strlist(&output,rover->d);
 
794
        sl->flags=rover->flags;
 
795
      }
 
796
 
 
797
  return output;
 
798
}
 
799
 
 
800
int
 
801
build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use )
 
802
{
 
803
    PK_LIST pk_list = NULL;
 
804
    PKT_public_key *pk=NULL;
 
805
    int rc=0;
 
806
    int any_recipients=0;
 
807
    STRLIST rov,remusr;
 
808
    char *def_rec = NULL;
 
809
 
 
810
    if(opt.grouplist)
 
811
      remusr=expand_group(rcpts);
 
812
    else
 
813
      remusr=rcpts;
 
814
 
 
815
    /* check whether there are any recipients in the list and build the
 
816
     * list of the encrypt-to ones (we always trust them) */
 
817
    for( rov = remusr; rov; rov = rov->next ) {
 
818
        if( !(rov->flags & 1) )
 
819
          {
 
820
            any_recipients = 1;
 
821
 
 
822
            if((rov->flags&2) && (PGP2 || PGP6 || PGP7 || PGP8))
 
823
              {
 
824
                log_info(_("you may not use %s while in %s mode\n"),
 
825
                         "--hidden-recipient",
 
826
                         compliance_option_string());
 
827
 
 
828
                compliance_failure();
 
829
              }
 
830
          }
 
831
        else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) {
 
832
            pk = xcalloc (1, sizeof *pk );
 
833
            pk->req_usage = use;
 
834
            /* We can encrypt-to a disabled key */
 
835
            if( (rc = get_pubkey_byname( pk, rov->d, NULL, NULL, 1 )) ) {
 
836
                free_public_key( pk ); pk = NULL;
 
837
                log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) );
 
838
                write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
 
839
                                              rov->d, strlen (rov->d), -1);
 
840
                goto fail;
 
841
            }
 
842
            else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) {
 
843
                /* Skip the actual key if the key is already present
 
844
                 * in the list */
 
845
                if (key_present_in_pk_list(pk_list, pk) == 0) {
 
846
                    free_public_key(pk); pk = NULL;
 
847
                    log_info(_("%s: skipped: public key already present\n"),
 
848
                                                            rov->d);
 
849
                }
 
850
                else {
 
851
                    PK_LIST r;
 
852
                    r = xmalloc ( sizeof *r );
 
853
                    r->pk = pk; pk = NULL;
 
854
                    r->next = pk_list;
 
855
                    r->flags = (rov->flags&2)?1:0;
 
856
                    pk_list = r;
 
857
 
 
858
                    if(r->flags&1 && (PGP2 || PGP6 || PGP7 || PGP8))
 
859
                      {
 
860
                        log_info(_("you may not use %s while in %s mode\n"),
 
861
                                 "--hidden-encrypt-to",
 
862
                                 compliance_option_string());
 
863
 
 
864
                        compliance_failure();
 
865
                      }
 
866
                }
 
867
            }
 
868
            else {
 
869
                free_public_key( pk ); pk = NULL;
 
870
                log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) );
 
871
                write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
 
872
                                              rov->d, strlen (rov->d), -1);
 
873
                goto fail;
 
874
            }
 
875
        }
 
876
    }
 
877
 
 
878
    if( !any_recipients && !opt.batch ) { /* ask */
 
879
        int have_def_rec;
 
880
        char *answer=NULL;
 
881
        STRLIST backlog=NULL;
 
882
 
 
883
        def_rec = default_recipient();
 
884
        have_def_rec = !!def_rec;
 
885
        if( !have_def_rec )
 
886
            tty_printf(_(
 
887
                "You did not specify a user ID. (you may use \"-r\")\n"));
 
888
        for(;;) {
 
889
            rc = 0;
 
890
            xfree (answer);
 
891
            if( have_def_rec ) {
 
892
                answer = def_rec;
 
893
                def_rec = NULL;
 
894
            }
 
895
            else if (backlog) {
 
896
              answer = strlist_pop (&backlog);
 
897
            }
 
898
            else {
 
899
                answer = cpr_get_utf8("pklist.user_id.enter",
 
900
                         _("\nEnter the user ID.  End with an empty line: "));
 
901
                trim_spaces(answer);
 
902
                cpr_kill_prompt();
 
903
            }
 
904
            if( !answer || !*answer ) {
 
905
                xfree (answer);
 
906
                break;
 
907
            }
 
908
            if(expand_id(answer,&backlog,0))
 
909
              continue;
 
910
            if( pk )
 
911
                free_public_key( pk );
 
912
            pk = xcalloc (1, sizeof *pk );
 
913
            pk->req_usage = use;
 
914
            rc = get_pubkey_byname( pk, answer, NULL, NULL, 0 );
 
915
            if( rc )
 
916
                tty_printf(_("No such user ID.\n"));
 
917
            else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) {
 
918
                if( have_def_rec ) {
 
919
                    if (key_present_in_pk_list(pk_list, pk) == 0) {
 
920
                        free_public_key(pk); pk = NULL;
 
921
                        log_info(_("skipped: public key "
 
922
                                   "already set as default recipient\n") );
 
923
                    }
 
924
                    else {
 
925
                        PK_LIST r = xmalloc ( sizeof *r );
 
926
                        r->pk = pk; pk = NULL;
 
927
                        r->next = pk_list;
 
928
                        r->flags = 0; /* no throwing default ids */
 
929
                        pk_list = r;
 
930
                    }
 
931
                    any_recipients = 1;
 
932
                    continue;
 
933
                }
 
934
                else {
 
935
                    int trustlevel;
 
936
                    
 
937
                    trustlevel = get_validity (pk, pk->user_id);
 
938
                    if( (trustlevel & TRUST_FLAG_DISABLED) ) {
 
939
                        tty_printf(_("Public key is disabled.\n") );
 
940
                    }
 
941
                    else if( do_we_trust_pre( pk, trustlevel ) ) {
 
942
                        /* Skip the actual key if the key is already present
 
943
                         * in the list */
 
944
                        if (key_present_in_pk_list(pk_list, pk) == 0) {
 
945
                            free_public_key(pk); pk = NULL;
 
946
                            log_info(_("skipped: public key already set\n") );
 
947
                        }
 
948
                        else {
 
949
                            PK_LIST r;
 
950
                            u32 keyid[2];
 
951
 
 
952
                            keyid_from_pk( pk, keyid);
 
953
                            tty_printf("Added %4u%c/%08lX %s \"",
 
954
                                       nbits_from_pk( pk ),
 
955
                                       pubkey_letter( pk->pubkey_algo ),
 
956
                                       (ulong)keyid[1],
 
957
                                       datestr_from_pk( pk ) );
 
958
                            if(pk->user_id)
 
959
                              tty_print_utf8_string(pk->user_id->name,
 
960
                                                    pk->user_id->len);
 
961
                            else
 
962
                              {
 
963
                                size_t n;
 
964
                                char *p = get_user_id( keyid, &n );
 
965
                                tty_print_utf8_string( p, n );
 
966
                                xfree (p);
 
967
                              }
 
968
                            tty_printf("\"\n");
 
969
 
 
970
                            r = xmalloc ( sizeof *r );
 
971
                            r->pk = pk; pk = NULL;
 
972
                            r->next = pk_list;
 
973
                            r->flags = 0; /* no throwing interactive ids */
 
974
                            pk_list = r;
 
975
                        }
 
976
                        any_recipients = 1;
 
977
                        continue;
 
978
                    }
 
979
                }
 
980
            }
 
981
            xfree (def_rec); def_rec = NULL;
 
982
            have_def_rec = 0;
 
983
        }
 
984
        if( pk ) {
 
985
            free_public_key( pk );
 
986
            pk = NULL;
 
987
        }
 
988
    }
 
989
    else if( !any_recipients && (def_rec = default_recipient()) ) {
 
990
        pk = xcalloc (1, sizeof *pk );
 
991
        pk->req_usage = use;
 
992
        /* The default recipient may be disabled */
 
993
        rc = get_pubkey_byname( pk, def_rec, NULL, NULL, 1 );
 
994
        if( rc )
 
995
            log_error(_("unknown default recipient `%s'\n"), def_rec );
 
996
        else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) {
 
997
          /* Mark any_recipients here since the default recipient
 
998
             would have been used if it wasn't already there.  It
 
999
             doesn't really matter if we got this key from the default
 
1000
             recipient or an encrypt-to. */
 
1001
          any_recipients = 1;
 
1002
          if (key_present_in_pk_list(pk_list, pk) == 0)
 
1003
            log_info(_("skipped: public key already set as default recipient\n"));
 
1004
          else {
 
1005
            PK_LIST r = xmalloc ( sizeof *r );
 
1006
            r->pk = pk; pk = NULL;
 
1007
            r->next = pk_list;
 
1008
            r->flags = 0; /* no throwing default ids */
 
1009
            pk_list = r;
 
1010
          }
 
1011
        }
 
1012
        if( pk ) {
 
1013
            free_public_key( pk );
 
1014
            pk = NULL;
 
1015
        }
 
1016
        xfree (def_rec); def_rec = NULL;
 
1017
    }
 
1018
    else {
 
1019
        any_recipients = 0;
 
1020
        for(; remusr; remusr = remusr->next ) {
 
1021
            if( (remusr->flags & 1) )
 
1022
                continue; /* encrypt-to keys are already handled */
 
1023
 
 
1024
            pk = xcalloc (1, sizeof *pk );
 
1025
            pk->req_usage = use;
 
1026
            if( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) {
 
1027
                free_public_key( pk ); pk = NULL;
 
1028
                log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) );
 
1029
                write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
 
1030
                                              remusr->d, strlen (remusr->d),
 
1031
                                              -1);
 
1032
                goto fail;
 
1033
            }
 
1034
            else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) {
 
1035
                int trustlevel;
 
1036
 
 
1037
                trustlevel = get_validity (pk, pk->user_id);
 
1038
                if( (trustlevel & TRUST_FLAG_DISABLED) ) {
 
1039
                    free_public_key(pk); pk = NULL;
 
1040
                    log_info(_("%s: skipped: public key is disabled\n"),
 
1041
                                                                    remusr->d);
 
1042
                    write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
 
1043
                                                  remusr->d,
 
1044
                                                  strlen (remusr->d),
 
1045
                                                  -1);
 
1046
                    rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
 
1047
                    goto fail;
 
1048
                }
 
1049
                else if( do_we_trust_pre( pk, trustlevel ) ) {
 
1050
                    /* note: do_we_trust may have changed the trustlevel */
 
1051
 
 
1052
                    /* We have at least one valid recipient. It doesn't matters
 
1053
                     * if this recipient is already present. */
 
1054
                    any_recipients = 1;
 
1055
 
 
1056
                    /* Skip the actual key if the key is already present
 
1057
                     * in the list */
 
1058
                    if (key_present_in_pk_list(pk_list, pk) == 0) {
 
1059
                        free_public_key(pk); pk = NULL;
 
1060
                        log_info(_("%s: skipped: public key already present\n"),
 
1061
                                                                    remusr->d);
 
1062
                    }
 
1063
                    else {
 
1064
                        PK_LIST r;
 
1065
                        r = xmalloc ( sizeof *r );
 
1066
                        r->pk = pk; pk = NULL;
 
1067
                        r->next = pk_list;
 
1068
                        r->flags = (remusr->flags&2)?1:0;
 
1069
                        pk_list = r;
 
1070
                    }
 
1071
                }
 
1072
                else { /* we don't trust this pk */
 
1073
                    free_public_key( pk ); pk = NULL;
 
1074
                    write_status_text_and_buffer (STATUS_INV_RECP, "10 ",
 
1075
                                                  remusr->d,
 
1076
                                                  strlen (remusr->d),
 
1077
                                                  -1);
 
1078
                    rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
 
1079
                    goto fail;
 
1080
                }
 
1081
            }
 
1082
            else {
 
1083
                free_public_key( pk ); pk = NULL;
 
1084
                write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
 
1085
                                              remusr->d,
 
1086
                                              strlen (remusr->d),
 
1087
                                              -1);
 
1088
                log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) );
 
1089
                goto fail;
 
1090
            }
 
1091
        }
 
1092
    }
 
1093
 
 
1094
    if( !rc && !any_recipients ) {
 
1095
        log_error(_("no valid addressees\n"));
 
1096
        write_status_text (STATUS_NO_RECP, "0");
 
1097
        rc = GPG_ERR_NO_USER_ID;
 
1098
    }
 
1099
 
 
1100
 fail:
 
1101
 
 
1102
    if( rc )
 
1103
        release_pk_list( pk_list );
 
1104
    else
 
1105
        *ret_pk_list = pk_list;
 
1106
    if(opt.grouplist)
 
1107
      free_strlist(remusr);
 
1108
    return rc;
 
1109
}
 
1110
 
 
1111
 
 
1112
/* In pgp6 mode, disallow all ciphers except IDEA (1), 3DES (2), and
 
1113
   CAST5 (3), all hashes except MD5 (1), SHA1 (2), and RIPEMD160 (3),
 
1114
   and all compressions except none (0) and ZIP (1).  pgp7 and pgp8
 
1115
   mode expands the cipher list to include AES128 (7), AES192 (8),
 
1116
   AES256 (9), and TWOFISH (10).  pgp8 adds the SHA-256 hash (8).  For
 
1117
   a true PGP key all of this is unneeded as they are the only items
 
1118
   present in the preferences subpacket, but checking here covers the
 
1119
   weird case of encrypting to a key that had preferences from a
 
1120
   different implementation which was then used with PGP.  I am not
 
1121
   completely comfortable with this as the right thing to do, as it
 
1122
   slightly alters the list of what the user is supposedly requesting.
 
1123
   It is not against the RFC however, as the preference chosen will
 
1124
   never be one that the user didn't specify somewhere ("The
 
1125
   implementation may use any mechanism to pick an algorithm in the
 
1126
   intersection"), and PGP has no mechanism to fix such a broken
 
1127
   preference list, so I'm including it. -dms */
 
1128
 
 
1129
int
 
1130
algo_available( preftype_t preftype, int algo, void *hint )
 
1131
{
 
1132
  if( preftype == PREFTYPE_SYM )
 
1133
    {
 
1134
      if(PGP6 && (algo != CIPHER_ALGO_IDEA
 
1135
                  && algo != CIPHER_ALGO_3DES
 
1136
                  && algo != CIPHER_ALGO_CAST5))
 
1137
        return 0;
 
1138
      
 
1139
      if((PGP7 || PGP8) && (algo != CIPHER_ALGO_IDEA
 
1140
                            && algo != CIPHER_ALGO_3DES
 
1141
                            && algo != CIPHER_ALGO_CAST5
 
1142
                            && algo != CIPHER_ALGO_AES
 
1143
                            && algo != CIPHER_ALGO_AES192
 
1144
                            && algo != CIPHER_ALGO_AES256
 
1145
                            && algo != CIPHER_ALGO_TWOFISH))
 
1146
        return 0;
 
1147
 
 
1148
      return algo && !gcry_cipher_test_algo (algo);
 
1149
    }
 
1150
  else if( preftype == PREFTYPE_HASH )
 
1151
    {
 
1152
      if(hint && ((*(int *)hint) != gcry_md_get_algo_dlen (algo)))
 
1153
        return 0;
 
1154
 
 
1155
      if((PGP6 || PGP7) && (algo != DIGEST_ALGO_MD5
 
1156
                            && algo != DIGEST_ALGO_SHA1
 
1157
                            && algo != DIGEST_ALGO_RMD160))
 
1158
        return 0;
 
1159
 
 
1160
 
 
1161
      if(PGP8 && (algo != DIGEST_ALGO_MD5
 
1162
                  && algo != DIGEST_ALGO_SHA1
 
1163
                  && algo != DIGEST_ALGO_RMD160
 
1164
                  && algo != DIGEST_ALGO_SHA256))
 
1165
        return 0;
 
1166
 
 
1167
      return algo && !gcry_md_test_algo( algo );
 
1168
    }
 
1169
  else if( preftype == PREFTYPE_ZIP )
 
1170
    {
 
1171
      if((PGP6 || PGP7 || PGP8) && (algo != COMPRESS_ALGO_NONE
 
1172
                                    && algo != COMPRESS_ALGO_ZIP))
 
1173
        return 0;
 
1174
 
 
1175
      return !check_compress_algo( algo );
 
1176
    }
 
1177
  else
 
1178
    return 0;
 
1179
}
 
1180
 
 
1181
 
 
1182
 
 
1183
/****************
 
1184
 * Return -1 if we could not find an algorithm.
 
1185
 */
 
1186
int
 
1187
select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint)
 
1188
{
 
1189
    PK_LIST pkr;
 
1190
    u32 bits[8];
 
1191
    const prefitem_t *prefs;
 
1192
    int i, j;
 
1193
    int compr_hack=0;
 
1194
    int any;
 
1195
 
 
1196
    if( !pk_list )
 
1197
        return -1;
 
1198
 
 
1199
    memset( bits, ~0, 8 * sizeof *bits );
 
1200
    for( pkr = pk_list; pkr; pkr = pkr->next ) {
 
1201
        u32 mask[8];
 
1202
 
 
1203
        memset( mask, 0, 8 * sizeof *mask );
 
1204
        if( preftype == PREFTYPE_SYM ) {
 
1205
          if( PGP2 &&
 
1206
              pkr->pk->version < 4 &&
 
1207
              pkr->pk->selfsigversion < 4 )
 
1208
            mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys
 
1209
                                  with v3 selfsigs (rfc2440:12.1) if
 
1210
                                  --pgp2 mode is on.  This doesn't
 
1211
                                  mean it's actually available, of
 
1212
                                  course. */
 
1213
          else
 
1214
            mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */
 
1215
        }
 
1216
        else if( preftype == PREFTYPE_HASH ) {
 
1217
          /* While I am including this code for completeness, note
 
1218
             that currently --pgp2 mode locks the hash at MD5, so this
 
1219
             function will never even be called.  Even if the hash
 
1220
             wasn't locked at MD5, we don't support sign+encrypt in
 
1221
             --pgp2 mode, and that's the only time PREFTYPE_HASH is
 
1222
             used anyway. -dms */
 
1223
          if( PGP2 &&
 
1224
              pkr->pk->version < 4 &&
 
1225
              pkr->pk->selfsigversion < 4 )
 
1226
            mask[0] |= (1<<1); /* MD5 is there for v3 keys with v3
 
1227
                                  selfsigs when --pgp2 is on. */
 
1228
          else
 
1229
            mask[0] |= (1<<2); /* SHA1 is there for everyone else */
 
1230
        }
 
1231
        else if( preftype == PREFTYPE_ZIP )
 
1232
          mask[0] |= (1<<0); /* Uncompressed is implicit */
 
1233
 
 
1234
        if (pkr->pk->user_id) /* selected by user ID */
 
1235
            prefs = pkr->pk->user_id->prefs;
 
1236
        else
 
1237
            prefs = pkr->pk->prefs;
 
1238
 
 
1239
        any = 0;
 
1240
        if( prefs ) {
 
1241
            for (i=0; prefs[i].type; i++ ) {
 
1242
                if( prefs[i].type == preftype ) {
 
1243
                    mask[prefs[i].value/32] |= 1 << (prefs[i].value%32);
 
1244
                    any = 1;
 
1245
                }
 
1246
            }
 
1247
        }
 
1248
 
 
1249
        if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) {
 
1250
            mask[0] |= 3; /* asume no_compression and old pgp */
 
1251
            compr_hack = 1;
 
1252
        }
 
1253
 
 
1254
#if 0
 
1255
        log_debug("pref mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
 
1256
               (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
 
1257
             (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);
 
1258
#endif
 
1259
        for(i=0; i < 8; i++ )
 
1260
            bits[i] &= mask[i];
 
1261
#if 0
 
1262
        log_debug("pref bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
 
1263
               (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
 
1264
             (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);
 
1265
#endif
 
1266
    }
 
1267
    /* usable algorithms are now in bits
 
1268
     * We now use the last key from pk_list to select
 
1269
     * the algorithm we want to use. there are no
 
1270
     * preferences for the last key, we select the one
 
1271
     * corresponding to first set bit.
 
1272
     */
 
1273
    i = -1;
 
1274
    any = 0;
 
1275
 
 
1276
    /* Can we use the requested algorithm? */
 
1277
    if(request>-1 && (bits[request/32] & (1<<(request%32))) &&
 
1278
       algo_available(preftype,request,hint))
 
1279
      return request;
 
1280
 
 
1281
    /* If we have personal prefs set, use them instead of the last key */
 
1282
    if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs)
 
1283
      prefs=opt.personal_cipher_prefs;
 
1284
    else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs)
 
1285
      prefs=opt.personal_digest_prefs;
 
1286
    else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs)
 
1287
      prefs=opt.personal_compress_prefs;
 
1288
 
 
1289
    if( prefs ) {
 
1290
        for(j=0; prefs[j].type; j++ ) {
 
1291
            if( prefs[j].type == preftype ) {
 
1292
                if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) {
 
1293
                    if( algo_available( preftype, prefs[j].value, hint ) ) {
 
1294
                        any = 1;
 
1295
                        i = prefs[j].value;
 
1296
                        break;
 
1297
                    }
 
1298
                }
 
1299
            }
 
1300
        }
 
1301
    }
 
1302
    if( !prefs || !any ) {
 
1303
        for(j=0; j < 256; j++ )
 
1304
            if( (bits[j/32] & (1<<(j%32))) ) {
 
1305
                if( algo_available( preftype, j, hint ) ) {
 
1306
                    i = j;
 
1307
                    break;
 
1308
                }
 
1309
            }
 
1310
    }
 
1311
 
 
1312
#if 0
 
1313
    log_debug("prefs of type %d: selected %d\n", preftype, i );
 
1314
#endif
 
1315
    if( compr_hack && !i ) {
 
1316
        /* selected no compression, but we should check whether
 
1317
         * algorithm 1 is also available (the ordering is not relevant
 
1318
         * in this case). */
 
1319
        if( bits[0] & (1<<1) )
 
1320
            i = 1; /* yep; we can use compression algo 1 */
 
1321
    }
 
1322
 
 
1323
    /* "If you are building an authentication system, the recipient
 
1324
       may specify a preferred signing algorithm. However, the signer
 
1325
       would be foolish to use a weak algorithm simply because the
 
1326
       recipient requests it." RFC2440:13.  If we settle on MD5, and
 
1327
       SHA1 is also available, use SHA1 instead.  Of course, if the
 
1328
       user intentionally chose MD5 (by putting it in their personal
 
1329
       prefs), then we should do what they say. */
 
1330
 
 
1331
    if(preftype==PREFTYPE_HASH &&
 
1332
       i==DIGEST_ALGO_MD5 && (bits[0] & (1<<DIGEST_ALGO_SHA1)))
 
1333
      {
 
1334
        i=DIGEST_ALGO_SHA1;
 
1335
 
 
1336
        if(opt.personal_digest_prefs)
 
1337
          for(j=0; prefs[j].type; j++ )
 
1338
            if(opt.personal_digest_prefs[j].type==PREFTYPE_HASH &&
 
1339
               opt.personal_digest_prefs[j].value==DIGEST_ALGO_MD5)
 
1340
              {
 
1341
                i=DIGEST_ALGO_MD5;
 
1342
                break;
 
1343
              }
 
1344
      }
 
1345
 
 
1346
    return i;
 
1347
}
 
1348
 
 
1349
/*
 
1350
 * Select the MDC flag from the pk_list.  We can only use MDC if all recipients
 
1351
 * support this feature 
 
1352
 */
 
1353
int
 
1354
select_mdc_from_pklist (PK_LIST pk_list)
 
1355
{
 
1356
    PK_LIST pkr;
 
1357
 
 
1358
    if( !pk_list )
 
1359
        return 0;
 
1360
 
 
1361
    for (pkr = pk_list; pkr; pkr = pkr->next) {
 
1362
        int mdc;
 
1363
 
 
1364
        if (pkr->pk->user_id) /* selected by user ID */
 
1365
            mdc = pkr->pk->user_id->mdc_feature;
 
1366
        else
 
1367
            mdc = pkr->pk->mdc_feature;
 
1368
        if (!mdc)
 
1369
            return 0; /* at least one recipient does not support it */
 
1370
    }
 
1371
    return 1; /* can be used */
 
1372
}