See ChangeLog: Mon Jul 26 09:34:46 CEST 1999 Werner Koch
[gnupg.git] / g10 / pkclist.c
1 /* pkclist.c
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "options.h"
29 #include "packet.h"
30 #include "errors.h"
31 #include "keydb.h"
32 #include "memory.h"
33 #include "util.h"
34 #include "trustdb.h"
35 #include "ttyio.h"
36 #include "status.h"
37 #include "i18n.h"
38
39
40 #define CONTROL_D ('D' - 'A' + 1)
41
42 /* fixme: we have nearly the same code in keyedit.c */
43 static void
44 print_fpr( PKT_public_key *pk )
45 {
46     byte array[MAX_FINGERPRINT_LEN], *p;
47     size_t i, n;
48
49     fingerprint_from_pk( pk, array, &n );
50     p = array;
51     /* Translators: this shoud fit into 24 bytes to that the fingerprint
52      * data is properly aligned with the user ID */
53     tty_printf(_("             Fingerprint:"));
54     if( n == 20 ) {
55         for(i=0; i < n ; i++, i++, p += 2 ) {
56             if( i == 10 )
57                 tty_printf(" ");
58             tty_printf(" %02X%02X", *p, p[1] );
59         }
60     }
61     else {
62         for(i=0; i < n ; i++, p++ ) {
63             if( i && !(i%8) )
64                 tty_printf(" ");
65             tty_printf(" %02X", *p );
66         }
67     }
68     tty_printf("\n");
69 }
70
71
72
73 static void
74 show_paths( ulong lid, int only_first )
75 {
76     void *context = NULL;
77     unsigned otrust, validity;
78     int last_level, level;
79
80     last_level = 0;
81     while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
82         char *p;
83         int c, rc;
84         size_t n;
85         u32 keyid[2];
86         PKT_public_key *pk ;
87
88         if( level < last_level && only_first )
89             break;
90         last_level = level;
91
92         rc = keyid_from_lid( lid, keyid );
93         if( rc ) {
94             log_error("ooops: can't get keyid for lid %lu\n", lid);
95             return;
96         }
97
98         pk = m_alloc_clear( sizeof *pk );
99         rc = get_pubkey( pk, keyid );
100         if( rc ) {
101             log_error("key %08lX: public key not found: %s\n",
102                                     (ulong)keyid[1], g10_errstr(rc) );
103             return;
104         }
105
106         tty_printf("%*s%4u%c/%08lX.%lu %s \"",
107                   level*2, "",
108                   nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
109                   (ulong)keyid[1], lid, datestr_from_pk( pk ) );
110
111         c = trust_letter(otrust);
112         if( c )
113             putchar( c );
114         else
115             printf( "%02x", otrust );
116         putchar('/');
117         c = trust_letter(validity);
118         if( c )
119             putchar( c );
120         else
121             printf( "%02x", validity );
122         putchar(' ');
123
124         p = get_user_id( keyid, &n );
125         tty_print_string( p, n ),
126         m_free(p);
127         tty_printf("\"\n");
128         free_public_key( pk );
129     }
130     enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
131     tty_printf("\n");
132 }
133
134
135
136
137 /****************
138  * Returns true if an ownertrust has changed.
139  */
140 static int
141 do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust, int defer_help )
142 {
143     char *p;
144     int rc;
145     size_t n;
146     u32 keyid[2];
147     PKT_public_key *pk ;
148     int changed=0;
149     int quit=0;
150     int show=0;
151     int did_help=defer_help;
152
153     rc = keyid_from_lid( lid, keyid );
154     if( rc ) {
155         log_error("ooops: can't get keyid for lid %lu\n", lid);
156         return 0;
157     }
158
159     pk = m_alloc_clear( sizeof *pk );
160     rc = get_pubkey( pk, keyid );
161     if( rc ) {
162         log_error("key %08lX: public key not found: %s\n",
163                                 (ulong)keyid[1], g10_errstr(rc) );
164         return 0;
165     }
166
167
168     for(;;) {
169         /* a string with valid answers */
170         char *ans = _("sSmMqQ");
171
172         if( !did_help ) {
173             if( !mode ) {
174                 tty_printf(_("No trust value assigned to %lu:\n"
175                            "%4u%c/%08lX %s \""), lid,
176                           nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
177                           (ulong)keyid[1], datestr_from_pk( pk ) );
178                 p = get_user_id( keyid, &n );
179                 tty_print_string( p, n ),
180                 m_free(p);
181                 tty_printf("\"\n");
182                 print_fpr( pk );
183                 tty_printf("\n");
184             }
185             tty_printf(_(
186 "Please decide how far you trust this user to correctly\n"
187 "verify other users' keys (by looking at passports,\n"
188 "checking fingerprints from different sources...)?\n\n"
189 " 1 = Don't know\n"
190 " 2 = I do NOT trust\n"
191 " 3 = I trust marginally\n"
192 " 4 = I trust fully\n"
193 " s = please show me more information\n") );
194             if( mode )
195                 tty_printf(_(" m = back to the main menu\n"));
196             else
197                 tty_printf(_(" q = quit\n"));
198             tty_printf("\n");
199             did_help = 1;
200         }
201         if( strlen(ans) != 6 )
202             BUG();
203         p = cpr_get("edit_ownertrust.value",_("Your decision? "));
204         trim_spaces(p);
205         cpr_kill_prompt();
206         if( !*p )
207             did_help = 0;
208         else if( *p && p[1] )
209             ;
210         else if( !p[1] && (*p >= '1' && *p <= '4') ) {
211             unsigned trust;
212             switch( *p ) {
213               case '1': trust = TRUST_UNDEFINED; break;
214               case '2': trust = TRUST_NEVER    ; break;
215               case '3': trust = TRUST_MARGINAL ; break;
216               case '4': trust = TRUST_FULLY    ; break;
217               default: BUG();
218             }
219             *new_trust = trust;
220             changed = 1;
221             break;
222         }
223         else if( *p == ans[0] || *p == ans[1] ) {
224             tty_printf(_(
225                 "Certificates leading to an ultimately trusted key:\n"));
226             show = 1;
227             break;
228         }
229         else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) {
230             break ; /* back to the menu */
231         }
232         else if( !mode && (*p == ans[4] || *p == ans[5] ) ) {
233             quit = 1;
234             break ; /* back to the menu */
235         }
236         m_free(p); p = NULL;
237     }
238     m_free(p);
239     m_free(pk);
240     return show? -2: quit? -1 : changed;
241 }
242
243
244 int
245 edit_ownertrust( ulong lid, int mode )
246 {
247     unsigned int trust;
248     int no_help = 0;
249
250     for(;;) {
251         switch( do_edit_ownertrust( lid, mode, &trust, no_help ) ) {
252           case -1:
253             return 0;
254           case -2:
255             show_paths( lid, 1  );
256             no_help = 1;
257             break;
258           case 1:
259             trust &= ~TRUST_FLAG_DISABLED;
260             trust |= get_ownertrust( lid ) & TRUST_FLAG_DISABLED;
261             if( !update_ownertrust( lid, trust ) )
262                 return 1;
263             return 0;
264           default:
265             return 0;
266         }
267     }
268 }
269
270 static int
271 add_ownertrust_cb( ulong lid )
272 {
273     unsigned trust;
274     int rc = do_edit_ownertrust( lid, 0, &trust, 0 );
275
276     if( rc == 1 )
277         return trust & TRUST_MASK;
278     return rc > 0? 0 : rc;
279 }
280
281 /****************
282  * Try to add some more owner trusts (interactive)
283  * This function presents all the signator in a certificate
284  * chain who have no ownertrust value assigned.
285  * Returns: -1 if no ownertrust were added.
286  */
287 static int
288 add_ownertrust( PKT_public_key *pk, int *quit, unsigned *trustlevel )
289 {
290     int rc;
291     unsigned flags = 0;
292
293     *quit = 0;
294     *trustlevel = 0;
295     tty_printf(
296 _("Could not find a valid trust path to the key.  Let's see whether we\n"
297   "can assign some missing owner trust values.\n\n"));
298
299     rc = check_trust( pk, trustlevel, NULL, add_ownertrust_cb, &flags );
300
301     if( !(flags & 1) )
302         tty_printf(_("No path leading to one of our keys found.\n\n") );
303     else if( !(flags & 2) )
304         tty_printf(_("No certificates with undefined trust found.\n\n") );
305     else if( !(flags & 4) )
306         tty_printf(_("No trust values changed.\n\n") );
307
308     return (flags & 4)? 0:-1;
309 }
310
311 /****************
312  * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
313  * Returns: true if we trust.
314  */
315 static int
316 do_we_trust( PKT_public_key *pk, int trustlevel )
317 {
318     int rc;
319     int did_add = 0;
320
321   retry:
322     if( (trustlevel & TRUST_FLAG_REVOKED) ) {
323         log_info(_("key %08lX: key has been revoked!\n"),
324                                         (ulong)keyid_from_pk( pk, NULL) );
325         if( opt.batch )
326             return 0;
327
328         if( !cpr_get_answer_is_yes("revoked_key.override",
329                                     _("Use this key anyway? ")) )
330             return 0;
331     }
332     else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
333         log_info(_("key %08lX: subkey has been revoked!\n"),
334                                         (ulong)keyid_from_pk( pk, NULL) );
335         if( opt.batch )
336             return 0;
337
338         if( !cpr_get_answer_is_yes("revoked_key.override",
339                                     _("Use this key anyway? ")) )
340             return 0;
341     }
342
343
344     switch( (trustlevel & TRUST_MASK) ) {
345       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
346         rc = insert_trust_record_by_pk( pk );
347         if( rc ) {
348             log_error("failed to insert it into the trustdb: %s\n",
349                                                       g10_errstr(rc) );
350             return 0; /* no */
351         }
352         rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
353         if( rc )
354             log_fatal("trust check after insert failed: %s\n",
355                                                       g10_errstr(rc) );
356         if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED ) {
357             log_debug("do_we_trust: oops at %d\n", __LINE__ );
358             return 0;
359         }
360         return do_we_trust( pk, trustlevel );
361
362       case TRUST_EXPIRED:
363         log_info(_("%08lX: key has expired\n"),
364                                     (ulong)keyid_from_pk( pk, NULL) );
365         return 0; /* no */
366
367       case TRUST_UNDEFINED:
368         if( opt.batch || opt.answer_no )
369             log_info(_("%08lX: no info to calculate a trust probability\n"),
370                                         (ulong)keyid_from_pk( pk, NULL) );
371         else {
372             int quit;
373
374             rc = add_ownertrust( pk, &quit, &trustlevel );
375             if( !rc && !did_add && !quit ) {
376                 did_add = 1;
377                 goto retry;
378             }
379         }
380         return 0;
381
382       case TRUST_NEVER:
383         log_info(_("%08lX: We do NOT trust this key\n"),
384                                         (ulong)keyid_from_pk( pk, NULL) );
385         return 0; /* no */
386
387       case TRUST_MARGINAL:
388         log_info(
389        _("%08lX: It is not sure that this key really belongs to the owner\n"
390          "but it is accepted anyway\n"), (ulong)keyid_from_pk( pk, NULL) );
391         return 1; /* yes */
392
393       case TRUST_FULLY:
394         if( opt.verbose )
395             log_info(_("This key probably belongs to the owner\n"));
396         return 1; /* yes */
397
398       case TRUST_ULTIMATE:
399         if( opt.verbose )
400             log_info(_("This key belongs to us\n"));
401         return 1; /* yes */
402
403       default: BUG();
404     }
405
406     return 1; /* yes */
407 }
408
409
410
411 /****************
412  * wrapper around do_we_trust, so we can ask whether to use the
413  * key anyway.
414  */
415 static int
416 do_we_trust_pre( PKT_public_key *pk, int trustlevel )
417 {
418     int rc;
419
420     rc = do_we_trust( pk, trustlevel );
421
422     if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
423         return 0;
424     if( (trustlevel & TRUST_FLAG_SUB_REVOKED) && !rc )
425         return 0;
426     else if( !opt.batch && !rc ) {
427         char *p;
428         u32 keyid[2];
429         size_t n;
430
431         keyid_from_pk( pk, keyid);
432         tty_printf( "%4u%c/%08lX %s \"",
433                   nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
434                   (ulong)keyid[1], datestr_from_pk( pk ) );
435         p = get_user_id( keyid, &n );
436         tty_print_string( p, n ),
437         m_free(p);
438         tty_printf("\"\n");
439         print_fpr( pk );
440         tty_printf("\n");
441
442         tty_printf(_(
443 "It is NOT certain that the key belongs to its owner.\n"
444 "If you *really* know what you are doing, you may answer\n"
445 "the next question with yes\n\n") );
446
447         if( cpr_get_answer_is_yes("untrusted_key.override",
448                                   _("Use this key anyway? "))  )
449             rc = 1;
450
451         /* Hmmm: Should we set a flag to tell the user the user about
452          *       his decision the next time he encrypts for this recipient?
453          */
454     }
455     else if( opt.always_trust && !rc ) {
456         log_info(_("WARNING: Using untrusted key!\n"));
457         rc = 1;
458     }
459     return rc;
460 }
461
462
463
464 /****************
465  * Check whether we can trust this signature.
466  * Returns: Error if we shall not trust this signatures.
467  */
468 int
469 check_signatures_trust( PKT_signature *sig )
470 {
471     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
472     int trustlevel;
473     int did_add = 0;
474     int rc=0;
475
476
477     if( opt.always_trust ) {
478         log_info(_("WARNING: Using untrusted key!\n"));
479         return 0;
480     }
481
482
483     rc = get_pubkey( pk, sig->keyid );
484     if( rc ) { /* this should not happen */
485         log_error("Ooops; the key vanished  - can't check the trust\n");
486         rc = G10ERR_NO_PUBKEY;
487         goto leave;
488     }
489
490     rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
491     if( rc ) {
492         log_error("check trust failed: %s\n", g10_errstr(rc));
493         goto leave;
494     }
495
496   retry:
497     if( (trustlevel & TRUST_FLAG_REVOKED) ) {
498         write_status( STATUS_KEYREVOKED );
499         log_info(_("WARNING: This key has been revoked by its owner!\n"));
500         log_info(_("         This could mean that the signature is forgery.\n"));
501     }
502     else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
503         write_status( STATUS_KEYREVOKED );
504         log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
505     }
506
507
508     switch( (trustlevel & TRUST_MASK) ) {
509       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
510         rc = insert_trust_record_by_pk( pk );
511         if( rc ) {
512             log_error("failed to insert it into the trustdb: %s\n",
513                                                       g10_errstr(rc) );
514             goto leave;
515         }
516         rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
517         if( rc )
518             log_fatal("trust check after insert failed: %s\n",
519                                                       g10_errstr(rc) );
520         if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
521             BUG();
522         goto retry;
523
524       case TRUST_EXPIRED:
525         log_info(_("Note: This key has expired!\n"));
526         break;
527
528       case TRUST_UNDEFINED:
529         if( did_add || opt.batch || opt.answer_no ) {
530             write_status( STATUS_TRUST_UNDEFINED );
531             log_info(_(
532             "WARNING: This key is not certified with a trusted signature!\n"));
533             log_info(_(
534             "         There is no indication that the "
535                                     "signature belongs to the owner.\n" ));
536         }
537         else {
538             int quit;
539             rc = add_ownertrust( pk, &quit, &trustlevel );
540             if( rc || quit ) {
541                 did_add = 1;
542                 rc = 0;
543             }
544             goto retry;
545         }
546         break;
547
548       case TRUST_NEVER:
549         write_status( STATUS_TRUST_NEVER );
550         log_info(_("WARNING: We do NOT trust this key!\n"));
551         log_info(_("         The signature is probably a FORGERY.\n"));
552         rc = G10ERR_BAD_SIGN;
553         break;
554
555       case TRUST_MARGINAL:
556         write_status( STATUS_TRUST_MARGINAL );
557         log_info(_(
558          "WARNING: This key is not certified with sufficiently trusted signatures!\n"
559                 ));
560         log_info(_(
561          "         It is not certain that the signature belongs to the owner.\n"
562                  ));
563         break;
564
565       case TRUST_FULLY:
566         write_status( STATUS_TRUST_FULLY );
567         break;
568
569       case TRUST_ULTIMATE:
570         write_status( STATUS_TRUST_ULTIMATE );
571         break;
572
573       default: BUG();
574     }
575
576
577   leave:
578     free_public_key( pk );
579     return rc;
580 }
581
582
583 void
584 release_pk_list( PK_LIST pk_list )
585 {
586     PK_LIST pk_rover;
587
588     for( ; pk_list; pk_list = pk_rover ) {
589         pk_rover = pk_list->next;
590         free_public_key( pk_list->pk );
591         m_free( pk_list );
592     }
593 }
594
595
596 static int
597 key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
598 {
599     for( ; pk_list; pk_list = pk_list->next)
600         if (cmp_public_keys(pk_list->pk, pk) == 0)
601             return 0;
602
603     return -1;
604 }
605
606
607 /****************
608  * Return a malloced string with a default reciepient if there is any
609  */
610 static char *
611 default_recipient(void)
612 {
613     PKT_secret_key *sk;
614     byte fpr[MAX_FINGERPRINT_LEN+1];
615     size_t n;
616     char *p;
617     int i;
618
619     if( opt.def_recipient )
620         return m_strdup( opt.def_recipient );
621     if( !opt.def_recipient_self )
622         return NULL;
623     sk = m_alloc_clear( sizeof *sk );
624     i = get_seckey_byname( sk, NULL, 0 );
625     if( i ) {
626         free_secret_key( sk );
627         return NULL;
628     }
629     n = MAX_FINGERPRINT_LEN;
630     fingerprint_from_sk( sk, fpr, &n );
631     free_secret_key( sk );
632     p = m_alloc( 2*n+3 );
633     *p++ = '0';
634     *p++ = 'x';
635     for(i=0; i < n; i++ )
636         sprintf( p+2*i, "%02X", fpr[i] );
637     p -= 2;
638     return p;
639 }
640
641
642 int
643 build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
644 {
645     PK_LIST pk_list = NULL;
646     PKT_public_key *pk=NULL;
647     int rc=0;
648     int any_recipients=0;
649     STRLIST rov;
650     char *def_rec = NULL;
651
652     /* check whether there are any recipients in the list and build the
653      * list of the encrypt-to ones (we always trust them) */
654     for( rov = remusr; rov; rov = rov->next ) {
655         if( !(rov->flags & 1) )
656             any_recipients = 1;
657         else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) {
658             pk = m_alloc_clear( sizeof *pk );
659             pk->pubkey_usage = use;
660             if( (rc = get_pubkey_byname( NULL, pk, rov->d, NULL )) ) {
661                 free_public_key( pk ); pk = NULL;
662                 log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
663             }
664             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
665
666                 /* Skip the actual key if the key is already present
667                  * in the list */
668                 if (key_present_in_pk_list(pk_list, pk) == 0) {
669                     free_public_key(pk); pk = NULL;
670                     log_info(_("%s: skipped: public key already present\n"),
671                                                             rov->d);
672                 }
673                 else {
674                     PK_LIST r;
675                     r = m_alloc( sizeof *r );
676                     r->pk = pk; pk = NULL;
677                     r->next = pk_list;
678                     r->mark = 0;
679                     pk_list = r;
680                 }
681             }
682             else {
683                 free_public_key( pk ); pk = NULL;
684                 log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
685             }
686         }
687     }
688
689     if( !any_recipients && !opt.batch ) { /* ask */
690         char *answer=NULL;
691         int have_def_rec;
692
693         def_rec = default_recipient();
694         have_def_rec = !!def_rec;
695         if( !have_def_rec )
696             tty_printf(_(
697                 "You did not specify a user ID. (you may use \"-r\")\n\n"));
698         for(;;) {
699             rc = 0;
700             m_free(answer);
701             if( have_def_rec ) {
702                 answer = def_rec;
703                 def_rec = NULL;
704             }
705             else {
706                 answer = cpr_get_utf8("pklist.user_id.enter",
707                                        _("Enter the user ID: "));
708                 trim_spaces(answer);
709                 cpr_kill_prompt();
710             }
711             if( !*answer )
712                 break;
713             if( pk )
714                 free_public_key( pk );
715             pk = m_alloc_clear( sizeof *pk );
716             pk->pubkey_usage = use;
717             rc = get_pubkey_byname( NULL, pk, answer, NULL );
718             if( rc )
719                 tty_printf(_("No such user ID.\n"));
720             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
721                 if( have_def_rec ) {
722                     PK_LIST r = m_alloc( sizeof *r );
723                     r->pk = pk; pk = NULL;
724                     r->next = pk_list;
725                     r->mark = 0;
726                     pk_list = r;
727                     any_recipients = 1;
728                     break;
729                 }
730                 else {
731                     int trustlevel;
732
733                     rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
734                     if( rc ) {
735                         log_error("error checking pk of `%s': %s\n",
736                                                      answer, g10_errstr(rc) );
737                     }
738                     else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
739                         tty_printf(_("Public key is disabled.\n") );
740                     }
741                     else if( do_we_trust_pre( pk, trustlevel ) ) {
742                         PK_LIST r;
743
744                         r = m_alloc( sizeof *r );
745                         r->pk = pk; pk = NULL;
746                         r->next = pk_list;
747                         r->mark = 0;
748                         pk_list = r;
749                         any_recipients = 1;
750                         break;
751                     }
752                 }
753             }
754             m_free(def_rec); def_rec = NULL;
755             have_def_rec = 0;
756         }
757         m_free(answer);
758         if( pk ) {
759             free_public_key( pk );
760             pk = NULL;
761         }
762     }
763     else if( !any_recipients && (def_rec = default_recipient()) ) {
764         pk = m_alloc_clear( sizeof *pk );
765         pk->pubkey_usage = use;
766         rc = get_pubkey_byname( NULL, pk, def_rec, NULL );
767         if( rc )
768             log_error(_("unknown default recipient `%s'\n"), def_rec );
769         else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
770             PK_LIST r = m_alloc( sizeof *r );
771             r->pk = pk; pk = NULL;
772             r->next = pk_list;
773             r->mark = 0;
774             pk_list = r;
775             any_recipients = 1;
776         }
777         if( pk ) {
778             free_public_key( pk );
779             pk = NULL;
780         }
781         m_free(def_rec); def_rec = NULL;
782     }
783     else {
784         any_recipients = 0;
785         for(; remusr; remusr = remusr->next ) {
786             if( (remusr->flags & 1) )
787                 continue; /* encrypt-to keys are already handled */
788
789             pk = m_alloc_clear( sizeof *pk );
790             pk->pubkey_usage = use;
791             if( (rc = get_pubkey_byname( NULL, pk, remusr->d, NULL )) ) {
792                 free_public_key( pk ); pk = NULL;
793                 log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
794             }
795             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
796                 int trustlevel;
797
798                 rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
799                 if( rc ) {
800                     free_public_key( pk ); pk = NULL;
801                     log_error(_("%s: error checking key: %s\n"),
802                                                       remusr->d, g10_errstr(rc) );
803                 }
804                 else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
805                     free_public_key(pk); pk = NULL;
806                     log_info(_("%s: skipped: public key is disabled\n"),
807                                                                     remusr->d);
808                 }
809                 else if( do_we_trust_pre( pk, trustlevel ) ) {
810                     /* note: do_we_trust may have changed the trustlevel */
811
812                     /* We have at least one valid recipient. It doesn't matters
813                      * if this recipient is already present. */
814                     any_recipients = 1;
815
816                     /* Skip the actual key if the key is already present
817                      * in the list */
818                     if (key_present_in_pk_list(pk_list, pk) == 0) {
819                         free_public_key(pk); pk = NULL;
820                         log_info(_("%s: skipped: public key already present\n"),
821                                                                     remusr->d);
822                     }
823                     else {
824                         PK_LIST r;
825                         r = m_alloc( sizeof *r );
826                         r->pk = pk; pk = NULL;
827                         r->next = pk_list;
828                         r->mark = 0;
829                         pk_list = r;
830                     }
831                 }
832                 else { /* we don't trust this pk */
833                     free_public_key( pk ); pk = NULL;
834                 }
835             }
836             else {
837                 free_public_key( pk ); pk = NULL;
838                 log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
839             }
840         }
841     }
842
843     if( !rc && !any_recipients ) {
844         log_error(_("no valid addressees\n"));
845         rc = G10ERR_NO_USER_ID;
846     }
847
848     if( rc )
849         release_pk_list( pk_list );
850     else
851         *ret_pk_list = pk_list;
852     return rc;
853 }
854
855
856
857 static int
858 algo_available( int preftype, int algo )
859 {
860     if( preftype == PREFTYPE_SYM ) {
861         if( algo == CIPHER_ALGO_TWOFISH )
862             return 0;  /* we don't want to generate Twofish messages for now*/
863         return algo && !check_cipher_algo( algo );
864     }
865     else if( preftype == PREFTYPE_HASH ) {
866         return algo && !check_digest_algo( algo );
867     }
868     else if( preftype == PREFTYPE_COMPR ) {
869         return !algo || algo == 1 || algo == 2;
870     }
871     else
872         return 0;
873 }
874
875 /****************
876  * Return -1 if we could not find an algorithm.
877  */
878 int
879 select_algo_from_prefs( PK_LIST pk_list, int preftype )
880 {
881     PK_LIST pkr;
882     u32 bits[8];
883     byte *pref = NULL;
884     size_t npref;
885     int i, j;
886     int compr_hack=0;
887     int any;
888
889     if( !pk_list )
890         return -1;
891
892     memset( bits, ~0, 8 * sizeof *bits );
893     for( pkr = pk_list; pkr; pkr = pkr->next ) {
894         u32 mask[8];
895
896         memset( mask, 0, 8 * sizeof *mask );
897         if( !pkr->pk->local_id ) { /* try to set the local id */
898             query_trust_info( pkr->pk, NULL );
899             if( !pkr->pk->local_id ) {
900                 log_debug("select_algo_from_prefs: can't get LID\n");
901                 continue;
902             }
903         }
904         if( preftype == PREFTYPE_SYM )
905             mask[0] |= (1<<2); /* 3DES is implicitly there */
906         m_free(pref);
907         pref = get_pref_data( pkr->pk->local_id, pkr->pk->namehash, &npref);
908         any = 0;
909         if( pref ) {
910            #if 0
911             log_hexdump("raw: ", pref, npref );
912            #endif
913             for(i=0; i+1 < npref; i+=2 ) {
914                 if( pref[i] == preftype ) {
915                     mask[pref[i+1]/32] |= 1 << (pref[i+1]%32);
916                     any = 1;
917                 }
918             }
919         }
920         if( (!pref || !any) && preftype == PREFTYPE_COMPR ) {
921             mask[0] |= 3; /* asume no_compression and old pgp */
922             compr_hack = 1;
923         }
924
925       #if 0
926         log_debug("mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
927                (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
928              (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);
929       #endif
930         for(i=0; i < 8; i++ )
931             bits[i] &= mask[i];
932       #if 0
933         log_debug("bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
934                (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
935              (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);
936       #endif
937     }
938     /* usable algorithms are now in bits
939      * We now use the last key from pk_list to select
940      * the algorithm we want to use. there are no
941      * preferences for the last key, we select the one
942      * corresponding to first set bit.
943      */
944     i = -1;
945     any = 0;
946     if( pref ) {
947         for(j=0; j+1 < npref; j+=2 ) {
948             if( pref[j] == preftype ) {
949                 if( (bits[pref[j+1]/32] & (1<<(pref[j+1]%32))) ) {
950                     if( algo_available( preftype, pref[j+1] ) ) {
951                         any = 1;
952                         i = pref[j+1];
953                         break;
954                     }
955                 }
956             }
957         }
958     }
959     if( !pref || !any ) {
960         for(j=0; j < 256; j++ )
961             if( (bits[j/32] & (1<<(j%32))) ) {
962                 if( algo_available( preftype, j ) ) {
963                     i = j;
964                     break;
965                 }
966             }
967     }
968   #if 0
969     log_debug("prefs of type %d: selected %d\n", preftype, i );
970   #endif
971     if( compr_hack && !i ) {
972         /* selected no compression, but we should check whether
973          * algorithm 1 is also available (the ordering is not relevant
974          * in this case). */
975         if( bits[0] & (1<<1) )
976             i = 1;  /* yep; we can use compression algo 1 */
977     }
978
979     m_free(pref);
980     return i;
981 }
982
983