See ChangeLog: Tue Mar 2 16:44:57 CET 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
43 static void
44 show_paths( ulong lid, int only_first )
45 {
46     void *context = NULL;
47     unsigned otrust, validity;
48     int last_level, level;
49
50     last_level = 0;
51     while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
52         char *p;
53         int rc;
54         size_t n;
55         u32 keyid[2];
56         PKT_public_key *pk ;
57
58         if( level < last_level && only_first )
59             break;
60         last_level = level;
61
62         rc = keyid_from_lid( lid, keyid );
63         if( rc ) {
64             log_error("ooops: can't get keyid for lid %lu\n", lid);
65             return;
66         }
67
68         pk = m_alloc_clear( sizeof *pk );
69         rc = get_pubkey( pk, keyid );
70         if( rc ) {
71             log_error("key %08lX: public key not found: %s\n",
72                                     (ulong)keyid[1], g10_errstr(rc) );
73             return;
74         }
75
76         tty_printf("%*s%4u%c/%08lX.%lu %s \"",
77                   level*2, "",
78                   nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
79                   (ulong)keyid[1], lid, datestr_from_pk( pk ) );
80      #if 0
81         c = trust_letter(otrust);
82         if( c )
83             putchar( c );
84         else
85             printf( "%02x", otrust );
86         putchar('/');
87         c = trust_letter(validity);
88         if( c )
89             putchar( c );
90         else
91             printf( "%02x", validity );
92         putchar(' ');
93       #endif
94
95
96         p = get_user_id( keyid, &n );
97         tty_print_string( p, n ),
98         m_free(p);
99         tty_printf("\"\n");
100         free_public_key( pk );
101     }
102     enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
103     tty_printf("\n");
104 }
105
106
107
108
109 /****************
110  * Returns true if an ownertrust has changed.
111  */
112 int
113 edit_ownertrust( ulong lid, int mode )
114 {
115     char *p;
116     int rc;
117     size_t n;
118     u32 keyid[2];
119     PKT_public_key *pk ;
120     int changed=0;
121     int quit=0;
122
123     rc = keyid_from_lid( lid, keyid );
124     if( rc ) {
125         log_error("ooops: can't get keyid for lid %lu\n", lid);
126         return 0;
127     }
128
129     pk = m_alloc_clear( sizeof *pk );
130     rc = get_pubkey( pk, keyid );
131     if( rc ) {
132         log_error("key %08lX: public key not found: %s\n",
133                                 (ulong)keyid[1], g10_errstr(rc) );
134         return 0;
135     }
136
137     if( !mode ) {
138         tty_printf(_("No trust value assigned to %lu:\n"
139                    "%4u%c/%08lX %s \""), lid,
140                   nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
141                   (ulong)keyid[1], datestr_from_pk( pk ) );
142         p = get_user_id( keyid, &n );
143         tty_print_string( p, n ),
144         m_free(p);
145         tty_printf("\"\n\n");
146     }
147     tty_printf(_(
148 "Please decide how far you trust this user to correctly\n"
149 "verify other users' keys (by looking at passports,\n"
150 "checking fingerprints from different sources...)?\n\n"
151 " 1 = Don't know\n"
152 " 2 = I do NOT trust\n"
153 " 3 = I trust marginally\n"
154 " 4 = I trust fully\n"
155 " s = please show me more information\n") );
156     if( mode )
157         tty_printf(_(" m = back to the main menu\n"));
158     else
159         tty_printf(_(" q = quit\n"));
160     tty_printf("\n");
161
162     for(;;) {
163         /* a string with valid answers */
164         char *ans = _("sSmMqQ");
165
166         if( strlen(ans) != 6 )
167             BUG();
168         p = cpr_get("edit_ownertrust.value",_("Your decision? "));
169         trim_spaces(p);
170         cpr_kill_prompt();
171         if( *p && p[1] )
172             ;
173         else if( !p[1] && (*p >= '1' && *p <= '4') ) {
174             unsigned trust;
175             switch( *p ) {
176               case '1': trust = TRUST_UNDEFINED; break;
177               case '2': trust = TRUST_NEVER    ; break;
178               case '3': trust = TRUST_MARGINAL ; break;
179               case '4': trust = TRUST_FULLY    ; break;
180               default: BUG();
181             }
182             if( !update_ownertrust( lid, trust ) )
183                 changed++;
184             break;
185         }
186         else if( *p == ans[0] || *p == ans[1] ) {
187             tty_printf(_(
188                 "Certificates leading to an ultimately trusted key:\n"));
189             show_paths( lid, 1  );
190         }
191         else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) {
192             break ; /* back to the menu */
193         }
194         else if( !mode && (*p == ans[4] || *p == ans[5] ) ) {
195             quit = 1;
196             break ; /* back to the menu */
197         }
198         m_free(p); p = NULL;
199     }
200     m_free(p);
201     m_free(pk);
202     return quit? -1 : changed;
203 }
204
205
206 /****************
207  * Try to add some more owner trusts (interactive)
208  * This function presents all the signator in a certificate
209  * chain who have no trust value assigned.
210  * Returns: -1 if no ownertrust were added.
211  */
212 static int
213 add_ownertrust( PKT_public_key *pk, int *quit )
214 {
215     int rc;
216     void *context = NULL;
217     ulong lid;
218     unsigned otrust, validity;
219     int any=0, changed=0, any_undefined=0;
220
221     *quit = 0;
222     tty_printf(
223 _("Could not find a valid trust path to the key.  Let's see whether we\n"
224   "can assign some missing owner trust values.\n\n"));
225
226     rc = query_trust_record( pk );
227     if( rc ) {
228         log_error("Ooops: not in trustdb\n");
229         return -1;
230     }
231
232     lid = pk->local_id;
233   #if 0  /* FIXME: enable this when trustdb stuff works again */
234     while( enum_cert_paths( &context, &lid, &otrust, &validity ) != -1 ) {
235         if( lid == pk->local_id )
236             continue;
237         any=1;
238         if( changed ) {
239             /* because enum_cert_paths() makes a snapshop of the
240              * trust paths, the otrust and validity are not anymore
241              * valid after changing an entry - we have to reread
242              * those values from then on
243              */
244             otrust = get_ownertrust( lid );
245         }
246         if( otrust == TRUST_UNDEFINED ) {
247             any_undefined=1;
248             enum_cert_paths_print( &context, NULL, changed, lid );
249             tty_printf("\n");
250             rc = edit_ownertrust( lid, 0 );
251             if( rc == -1 ) {
252                 *quit = 1;
253                 break;
254             }
255             else if( rc > 0 )
256                changed = 1;
257         }
258     }
259     enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
260   #endif
261
262     if( !any )
263         tty_printf(_("No path leading to one of our keys found.\n\n") );
264     else if( !any_undefined )
265         tty_printf(_("No certificates with undefined trust found.\n\n") );
266     else if( !changed )
267         tty_printf(_("No trust values changed.\n\n") );
268
269     return changed? 0:-1;
270 }
271
272 /****************
273  * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
274  * Returns: true if we trust.
275  */
276 static int
277 do_we_trust( PKT_public_key *pk, int trustlevel )
278 {
279     int rc;
280
281     if( (trustlevel & TRUST_FLAG_REVOKED) ) {
282         log_info(_("key %08lX: key has been revoked!\n"),
283                                         (ulong)keyid_from_pk( pk, NULL) );
284         if( opt.batch )
285             return 0;
286
287         if( !cpr_get_answer_is_yes("revoked_key.override",
288                                     _("Use this key anyway? ")) )
289             return 0;
290     }
291
292
293     switch( (trustlevel & TRUST_MASK) ) {
294       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
295         rc = insert_trust_record( pk );
296         if( rc ) {
297             log_error("failed to insert it into the trustdb: %s\n",
298                                                       g10_errstr(rc) );
299             return 0; /* no */
300         }
301         rc = check_trust( pk, &trustlevel );
302         if( rc )
303             log_fatal("trust check after insert failed: %s\n",
304                                                       g10_errstr(rc) );
305         if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
306             BUG();
307         return do_we_trust( pk, trustlevel );
308
309       case TRUST_EXPIRED:
310         log_info(_("%08lX: key has expired\n"),
311                                     (ulong)keyid_from_pk( pk, NULL) );
312         return 0; /* no */
313
314       case TRUST_UNDEFINED:
315         if( opt.batch || opt.answer_no )
316             log_info(_("%08lX: no info to calculate a trust probability\n"),
317                                         (ulong)keyid_from_pk( pk, NULL) );
318         else {
319             int quit;
320
321             rc = add_ownertrust( pk, &quit );
322             if( !rc && !quit ) {
323                 rc = check_trust( pk, &trustlevel );
324                 if( rc )
325                     log_fatal("trust check after add_ownertrust failed: %s\n",
326                                                               g10_errstr(rc) );
327                 /* fixme: this is recursive; we should unroll it */
328                 return do_we_trust( pk, trustlevel );
329             }
330         }
331         return 0;
332
333       case TRUST_NEVER:
334         log_info(_("%08lX: We do NOT trust this key\n"),
335                                         (ulong)keyid_from_pk( pk, NULL) );
336         return 0; /* no */
337
338       case TRUST_MARGINAL:
339         log_info(
340        _("%08lX: It is not sure that this key really belongs to the owner\n"
341          "but it is accepted anyway\n"), (ulong)keyid_from_pk( pk, NULL) );
342         return 1; /* yes */
343
344       case TRUST_FULLY:
345         if( opt.verbose )
346             log_info(_("This key probably belongs to the owner\n"));
347         return 1; /* yes */
348
349       case TRUST_ULTIMATE:
350         if( opt.verbose )
351             log_info(_("This key belongs to us\n"));
352         return 1; /* yes */
353
354       default: BUG();
355     }
356
357
358     /* Eventuell fragen falls der trustlevel nicht ausreichend ist */
359
360
361     return 1; /* yes */
362 }
363
364
365 /****************
366  * wrapper around do_we_trust, so we can ask whether to use the
367  * key anyway.
368  */
369 static int
370 do_we_trust_pre( PKT_public_key *pk, int trustlevel )
371 {
372     int rc;
373
374     rc = do_we_trust( pk, trustlevel );
375
376     if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
377         return 0;
378     else if( !opt.batch && !rc ) {
379         char *p;
380         u32 keyid[2];
381         size_t n;
382
383         keyid_from_pk( pk, keyid);
384         tty_printf( "%4u%c/%08lX %s \"",
385                   nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
386                   (ulong)keyid[1], datestr_from_pk( pk ) );
387         p = get_user_id( keyid, &n );
388         tty_print_string( p, n ),
389         m_free(p);
390         tty_printf("\"\n\n");
391
392         tty_printf(_(
393 "It is NOT certain that the key belongs to its owner.\n"
394 "If you *really* know what you are doing, you may answer\n"
395 "the next question with yes\n\n") );
396
397         if( cpr_get_answer_is_yes("untrusted_key.override",
398                                   _("Use this key anyway? "))  )
399             rc = 1;
400
401         /* Hmmm: Should we set a flag to tell the user the user about
402          *       his decision the next time he encrypts for this recipient?
403          */
404     }
405     else if( opt.always_trust && !rc ) {
406         log_info(_("WARNING: Using untrusted key!\n"));
407         rc = 1;
408     }
409     return rc;
410 }
411
412
413
414 /****************
415  * Check whether we can trust this signature.
416  * Returns: Error if we shall not trust this signatures.
417  */
418 int
419 check_signatures_trust( PKT_signature *sig )
420 {
421     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
422     int trustlevel;
423     int dont_try = 0;
424     int rc=0;
425
426     rc = get_pubkey( pk, sig->keyid );
427     if( rc ) { /* this should not happen */
428         log_error("Ooops; the key vanished  - can't check the trust\n");
429         rc = G10ERR_NO_PUBKEY;
430         goto leave;
431     }
432
433   retry:
434     rc = check_trust( pk, &trustlevel );
435     if( rc ) {
436         log_error("check trust failed: %s\n", g10_errstr(rc));
437         goto leave;
438     }
439
440     if( (trustlevel & TRUST_FLAG_REVOKED) ) {
441         write_status( STATUS_KEYREVOKED );
442         log_info(_("WARNING: This key has been revoked by its owner!\n"));
443         log_info(_("         This could mean that the signature is forgery.\n"));
444     }
445
446
447     switch( (trustlevel & TRUST_MASK) ) {
448       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
449         rc = insert_trust_record( pk );
450         if( rc ) {
451             log_error("failed to insert it into the trustdb: %s\n",
452                                                       g10_errstr(rc) );
453             goto leave;
454         }
455         rc = check_trust( pk, &trustlevel );
456         if( rc )
457             log_fatal("trust check after insert failed: %s\n",
458                                                       g10_errstr(rc) );
459         if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
460             BUG();
461         goto retry;
462
463       case TRUST_EXPIRED:
464         log_info(_("Note: This key has expired!\n"));
465         break;
466
467       case TRUST_UNDEFINED:
468         if( dont_try || opt.batch || opt.answer_no ) {
469             write_status( STATUS_TRUST_UNDEFINED );
470             log_info(_(
471             "WARNING: This key is not certified with a trusted signature!\n"));
472             log_info(_(
473             "         There is no indication that the "
474                                     "signature belongs to the owner.\n" ));
475         }
476         else {
477             int quit;
478             rc = add_ownertrust( pk, &quit );
479             if( rc || quit ) {
480                 dont_try = 1;
481                 rc = 0;
482             }
483             goto retry;
484         }
485         break;
486
487       case TRUST_NEVER:
488         write_status( STATUS_TRUST_NEVER );
489         log_info(_("WARNING: We do NOT trust this key!\n"));
490         log_info(_("         The signature is probably a FORGERY.\n"));
491         rc = G10ERR_BAD_SIGN;
492         break;
493
494       case TRUST_MARGINAL:
495         write_status( STATUS_TRUST_MARGINAL );
496         log_info(_(
497          "WARNING: This key is not certified with sufficiently trusted signatures!\n"
498                 ));
499         log_info(_(
500          "         It is not certain that the signature belongs to the owner.\n"
501                  ));
502         break;
503
504       case TRUST_FULLY:
505         write_status( STATUS_TRUST_FULLY );
506         break;
507
508       case TRUST_ULTIMATE:
509         write_status( STATUS_TRUST_ULTIMATE );
510         break;
511
512       default: BUG();
513     }
514
515
516   leave:
517     free_public_key( pk );
518     return rc;
519 }
520
521
522 void
523 release_pk_list( PK_LIST pk_list )
524 {
525     PK_LIST pk_rover;
526
527     for( ; pk_list; pk_list = pk_rover ) {
528         pk_rover = pk_list->next;
529         free_public_key( pk_list->pk );
530         m_free( pk_list );
531     }
532 }
533
534 int
535 build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
536 {
537     PK_LIST pk_list = NULL;
538     PKT_public_key *pk=NULL;
539     int rc=0;
540     int any_recipients=0;
541     STRLIST rov;
542
543     /* check whether there are any recipients in the list and build the
544      * list of the encrypt-to ones (we always trust them) */
545     for( rov = remusr; rov; rov = rov->next ) {
546         if( !(rov->flags & 1) )
547             any_recipients = 1;
548         else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) {
549             pk = m_alloc_clear( sizeof *pk );
550             pk->pubkey_usage = use;
551             if( (rc = get_pubkey_byname( NULL, pk, rov->d, NULL )) ) {
552                 free_public_key( pk ); pk = NULL;
553                 log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
554             }
555             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
556                 PK_LIST r;
557
558                 r = m_alloc( sizeof *r );
559                 r->pk = pk; pk = NULL;
560                 r->next = pk_list;
561                 r->mark = 0;
562                 pk_list = r;
563             }
564             else {
565                 free_public_key( pk ); pk = NULL;
566                 log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
567             }
568         }
569     }
570
571     if( !any_recipients && !opt.batch ) { /* ask */
572         char *answer=NULL;
573
574         tty_printf(_(
575                 "You did not specify a user ID. (you may use \"-r\")\n\n"));
576         for(;;) {
577             rc = 0;
578             m_free(answer);
579             answer = cpr_get_utf8("pklist.user_id.enter",
580                                    _("Enter the user ID: "));
581             trim_spaces(answer);
582             cpr_kill_prompt();
583             if( !*answer )
584                 break;
585             if( pk )
586                 free_public_key( pk );
587             pk = m_alloc_clear( sizeof *pk );
588             pk->pubkey_usage = use;
589             rc = get_pubkey_byname( NULL, pk, answer, NULL );
590             if( rc )
591                 tty_printf(_("No such user ID.\n"));
592             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
593                 int trustlevel;
594
595                 rc = check_trust( pk, &trustlevel );
596                 if( rc ) {
597                     log_error("error checking pk of `%s': %s\n",
598                                                       answer, g10_errstr(rc) );
599                 }
600                 else if( do_we_trust_pre( pk, trustlevel ) ) {
601                     PK_LIST r;
602
603                     r = m_alloc( sizeof *r );
604                     r->pk = pk; pk = NULL;
605                     r->next = pk_list;
606                     r->mark = 0;
607                     pk_list = r;
608                     any_recipients = 1;
609                     break;
610                 }
611             }
612         }
613         m_free(answer);
614         if( pk ) {
615             free_public_key( pk );
616             pk = NULL;
617         }
618     }
619     else {
620         any_recipients = 0;
621         for(; remusr; remusr = remusr->next ) {
622             if( (remusr->flags & 1) )
623                 continue; /* encrypt-to keys are already handled */
624
625             pk = m_alloc_clear( sizeof *pk );
626             pk->pubkey_usage = use;
627             if( (rc = get_pubkey_byname( NULL, pk, remusr->d, NULL )) ) {
628                 free_public_key( pk ); pk = NULL;
629                 log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
630             }
631             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
632                 int trustlevel;
633
634                 rc = check_trust( pk, &trustlevel );
635                 if( rc ) {
636                     free_public_key( pk ); pk = NULL;
637                     log_error(_("%s: error checking key: %s\n"),
638                                                       remusr->d, g10_errstr(rc) );
639                 }
640                 else if( do_we_trust_pre( pk, trustlevel ) ) {
641                     /* note: do_we_trust may have changed the trustlevel */
642                     PK_LIST r;
643
644                     r = m_alloc( sizeof *r );
645                     r->pk = pk; pk = NULL;
646                     r->next = pk_list;
647                     r->mark = 0;
648                     pk_list = r;
649                     any_recipients = 1;
650                 }
651                 else { /* we don't trust this pk */
652                     free_public_key( pk ); pk = NULL;
653                 }
654             }
655             else {
656                 free_public_key( pk ); pk = NULL;
657                 log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
658             }
659         }
660     }
661
662     if( !rc && !any_recipients ) {
663         log_error(_("no valid addressees\n"));
664         rc = G10ERR_NO_USER_ID;
665     }
666
667     if( rc )
668         release_pk_list( pk_list );
669     else
670         *ret_pk_list = pk_list;
671     return rc;
672 }
673
674
675
676 static int
677 algo_available( int preftype, int algo )
678 {
679     if( preftype == PREFTYPE_SYM ) {
680         return algo && !check_cipher_algo( algo );
681     }
682     else if( preftype == PREFTYPE_HASH ) {
683         return algo && !check_digest_algo( algo );
684     }
685     else if( preftype == PREFTYPE_COMPR ) {
686         return !algo || algo == 1 || algo == 2;
687     }
688     else
689         return 0;
690 }
691
692 /****************
693  * Return -1 if we could not find an algorithm.
694  */
695 int
696 select_algo_from_prefs( PK_LIST pk_list, int preftype )
697 {
698     PK_LIST pkr;
699     u32 bits[8];
700     byte *pref = NULL;
701     size_t npref;
702     int i, j;
703     int compr_hack=0;
704     int any;
705
706     if( !pk_list )
707         return -1;
708
709     memset( bits, ~0, 8 * sizeof *bits );
710     for( pkr = pk_list; pkr; pkr = pkr->next ) {
711         u32 mask[8];
712
713         memset( mask, 0, 8 * sizeof *mask );
714         if( !pkr->pk->local_id ) { /* try to set the local id */
715             query_trust_info( pkr->pk );
716             if( !pkr->pk->local_id ) {
717                 log_debug("select_algo_from_prefs: can't get LID\n");
718                 continue;
719             }
720         }
721         if( preftype == PREFTYPE_SYM )
722             mask[0] |= (1<<2); /* 3DES is implicitly there */
723         m_free(pref);
724         pref = get_pref_data( pkr->pk->local_id, pkr->pk->namehash, &npref);
725         any = 0;
726         if( pref ) {
727            #if 0
728             log_hexdump("raw: ", pref, npref );
729            #endif
730             for(i=0; i+1 < npref; i+=2 ) {
731                 if( pref[i] == preftype ) {
732                     mask[pref[i+1]/32] |= 1 << (pref[i+1]%32);
733                     any = 1;
734                 }
735             }
736         }
737         if( (!pref || !any) && preftype == PREFTYPE_COMPR ) {
738             mask[0] |= 3; /* asume no_compression and old pgp */
739             compr_hack = 1;
740         }
741
742       #if 0
743         log_debug("mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
744                (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
745              (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);
746       #endif
747         for(i=0; i < 8; i++ )
748             bits[i] &= mask[i];
749       #if 0
750         log_debug("bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
751                (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
752              (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);
753       #endif
754     }
755     /* usable algorithms are now in bits
756      * We now use the last key from pk_list to select
757      * the algorithm we want to use. there are no
758      * preferences for the last key, we select the one
759      * corresponding to first set bit.
760      */
761     i = -1;
762     any = 0;
763     if( pref ) {
764         for(j=0; j+1 < npref; j+=2 ) {
765             if( pref[j] == preftype ) {
766                 any = 1;
767                 if( (bits[pref[j+1]/32] & (1<<(pref[j+1]%32))) ) {
768                     if( algo_available( preftype, pref[j+1] ) ) {
769                         i = pref[j+1];
770                         break;
771                     }
772                 }
773             }
774         }
775     }
776     if( !pref || !any ) {
777         for(j=0; j < 256; j++ )
778             if( (bits[j/32] & (1<<(j%32))) ) {
779                 if( algo_available( preftype, j ) ) {
780                     i = j;
781                     break;
782                 }
783             }
784     }
785   #if 0
786     log_debug("prefs of type %d: selected %d\n", preftype, i );
787   #endif
788     if( compr_hack && !i ) {
789         /* selected no compression, but we should check whether
790          * algorithm 1 is also available (the ordering is not relevant
791          * in this case). */
792         if( bits[0] & (1<<1) )
793             i = 1;  /* yep; we can use compression algo 1 */
794     }
795
796     m_free(pref);
797     return i;
798 }
799
800