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