* keyedit.c (menu_revsig): Properly show a uid is revoked without
[gnupg.git] / g10 / misc.c
1 /* misc.c -  miscellaneous functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 <unistd.h>
26 #include <errno.h>
27 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
28   #include <asm/sysinfo.h>
29   #include <asm/unistd.h>
30 #endif
31 #ifdef HAVE_SETRLIMIT
32   #include <time.h>
33   #include <sys/time.h>
34   #include <sys/resource.h>
35 #endif
36 #include "util.h"
37 #include "main.h"
38 #include "photoid.h"
39 #include "options.h"
40 #include "i18n.h"
41
42
43 const char *g10m_revision_string(int);
44 const char *g10c_revision_string(int);
45 const char *g10u_revision_string(int);
46
47 #ifdef __GNUC__
48 volatile
49 #endif
50          void
51 pull_in_libs(void)
52 {
53     g10m_revision_string(0);
54     g10c_revision_string(0);
55     g10u_revision_string(0);
56 }
57
58
59 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
60 static int
61 setsysinfo(unsigned long op, void *buffer, unsigned long size,
62                      int *start, void *arg, unsigned long flag)
63 {
64     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
65 }
66
67 void
68 trap_unaligned(void)
69 {
70     unsigned int buf[2];
71
72     buf[0] = SSIN_UACPROC;
73     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
74     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
75 }
76 #else
77 void
78 trap_unaligned(void)
79 {  /* dummy */
80 }
81 #endif
82
83
84 int
85 disable_core_dumps()
86 {
87  #ifdef HAVE_DOSISH_SYSTEM
88     return 0;
89  #else
90   #ifdef HAVE_SETRLIMIT
91     struct rlimit limit;
92
93     limit.rlim_cur = 0;
94     limit.rlim_max = 0;
95     if( !setrlimit( RLIMIT_CORE, &limit ) )
96         return 0;
97     if( errno != EINVAL && errno != ENOSYS )
98         log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
99   #endif
100     return 1;
101  #endif
102 }
103
104
105
106 u16
107 checksum_u16( unsigned n )
108 {
109     u16 a;
110
111     a  = (n >> 8) & 0xff;
112     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM ) {
113        a |= n & 0xff;
114        log_debug("csum_u16 emulated for n=%u\n", n);
115     }
116     else
117        a += n & 0xff;
118     return a;
119 }
120
121 static u16
122 checksum_u16_nobug( unsigned n )
123 {
124     u16 a;
125
126     a  = (n >> 8) & 0xff;
127     a += n & 0xff;
128     return a;
129 }
130
131 u16
132 checksum( byte *p, unsigned n )
133 {
134     u16 a;
135
136     for(a=0; n; n-- )
137         a += *p++;
138     return a;
139 }
140
141 u16
142 checksum_mpi( MPI a )
143 {
144     u16 csum;
145     byte *buffer;
146     unsigned nbytes;
147     unsigned nbits;
148
149     buffer = mpi_get_buffer( a, &nbytes, NULL );
150     /* some versions of gpg encode wrong values for the length of an mpi
151      * so that mpi_get_nbits() which counts the mpi yields another (shorter)
152      * value than the one store with the mpi.  mpi_get_nbit_info() returns
153      * this stored value if it is still available.
154      */
155
156     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM )
157         nbits = 0;
158     else
159         nbits = mpi_get_nbit_info(a);
160     if( !nbits )
161        nbits = mpi_get_nbits(a);
162     csum = checksum_u16( nbits );
163     csum += checksum( buffer, nbytes );
164     m_free( buffer );
165     return csum;
166 }
167
168 /****************
169  * This is the correct function
170  */
171 u16
172 checksum_mpi_counted_nbits( MPI a )
173 {
174     u16 csum;
175     byte *buffer;
176     unsigned nbytes;
177     unsigned nbits;
178
179     buffer = mpi_get_buffer( a, &nbytes, NULL );
180     nbits = mpi_get_nbits(a);
181     mpi_set_nbit_info(a,nbits);
182     csum = checksum_u16_nobug( nbits );
183     csum += checksum( buffer, nbytes );
184     m_free( buffer );
185     return csum;
186 }
187
188
189 u32
190 buffer_to_u32( const byte *buffer )
191 {
192     unsigned long a;
193     a =  *buffer << 24;
194     a |= buffer[1] << 16;
195     a |= buffer[2] << 8;
196     a |= buffer[3];
197     return a;
198 }
199
200
201 static void
202 no_exp_algo(void)
203 {
204     static int did_note = 0;
205
206     if( !did_note ) {
207         did_note = 1;
208         log_info(_("Experimental algorithms should not be used!\n"));
209     }
210 }
211
212 void
213 print_pubkey_algo_note( int algo )
214 {
215     if( algo >= 100 && algo <= 110 )
216         no_exp_algo();
217 }
218
219 void
220 print_cipher_algo_note( int algo )
221 {
222     if( algo >= 100 && algo <= 110 )
223         no_exp_algo();
224     else if(    algo == CIPHER_ALGO_3DES
225              || algo == CIPHER_ALGO_CAST5
226              || algo == CIPHER_ALGO_BLOWFISH
227              || algo == CIPHER_ALGO_TWOFISH
228              || algo == CIPHER_ALGO_RIJNDAEL
229              || algo == CIPHER_ALGO_RIJNDAEL192
230              || algo == CIPHER_ALGO_RIJNDAEL256
231            )
232         ;
233     else {
234         static int did_note = 0;
235
236         if( !did_note ) {
237             did_note = 1;
238             log_info(_("this cipher algorithm is deprecated; "
239                        "please use a more standard one!\n"));
240         }
241     }
242 }
243
244 void
245 print_digest_algo_note( int algo )
246 {
247     if( algo >= 100 && algo <= 110 )
248         no_exp_algo();
249 }
250
251
252 /* Return a string which is used as a kind of process ID */
253 const byte *
254 get_session_marker( size_t *rlen )
255 {
256     static byte marker[SIZEOF_UNSIGNED_LONG*2];
257     static int initialized;
258
259     if ( !initialized ) {
260         volatile ulong aa, bb; /* we really want the uninitialized value */
261         ulong a, b;
262
263         initialized = 1;
264         /* also this marker is guessable it is not easy to use this 
265          * for a faked control packet because an attacker does not
266          * have enough control about the time the verification does 
267          * take place.  Of course, we can add just more random but 
268          * than we need the random generator even for verification
269          * tasks - which does not make sense. */
270         a = aa ^ (ulong)getpid();
271         b = bb ^ (ulong)time(NULL);
272         memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
273         memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
274     }
275     *rlen = sizeof(marker);
276     return marker;
277 }
278
279 /****************
280  * Wrapper around the libgcrypt function with addional checks on
281  * openPGP contraints for the algo ID.
282  */
283 int
284 openpgp_cipher_test_algo( int algo )
285 {
286     if( algo < 0 || algo > 110 )
287         return G10ERR_CIPHER_ALGO;
288     return check_cipher_algo(algo);
289 }
290
291 int
292 openpgp_pk_test_algo( int algo, unsigned int usage_flags )
293 {
294     if( algo < 0 || algo > 110 )
295         return G10ERR_PUBKEY_ALGO;
296     return check_pubkey_algo2( algo, usage_flags );
297 }
298
299 int 
300 openpgp_pk_algo_usage ( int algo )
301 {
302     int use = 0; 
303     
304     /* they are hardwired in gpg 1.0 */
305     switch ( algo ) {    
306       case PUBKEY_ALGO_RSA:
307           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
308           break;
309       case PUBKEY_ALGO_RSA_E:
310           use = PUBKEY_USAGE_ENC;
311           break;
312       case PUBKEY_ALGO_RSA_S:
313           use = PUBKEY_USAGE_SIG;
314           break;
315       case PUBKEY_ALGO_ELGAMAL_E:
316           use = PUBKEY_USAGE_ENC;
317           break;
318       case PUBKEY_ALGO_DSA:  
319           use = PUBKEY_USAGE_SIG;
320           break;
321       case PUBKEY_ALGO_ELGAMAL:
322           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
323           break;
324       default:
325           break;
326     }
327     return use;
328 }
329
330 int
331 openpgp_md_test_algo( int algo )
332 {
333     if( algo < 0 || algo > 110 )
334         return G10ERR_DIGEST_ALGO;
335     return check_digest_algo(algo);
336 }
337
338 /* Special warning for the IDEA cipher */
339 void
340 idea_cipher_warn(int show)
341 {
342   static int warned=0;
343
344   if(!warned || show)
345     {
346       log_info(_("the IDEA cipher plugin is not present\n"));
347       log_info(_("please see http://www.gnupg.org/why-not-idea.html "
348                  "for more information\n"));
349       warned=1;
350     }
351 }
352
353 /* Expand %-strings.  Returns a string which must be m_freed.  Returns
354    NULL if the string cannot be expanded (too large). */
355 char *
356 pct_expando(const char *string,struct expando_args *args)
357 {
358   const char *ch=string;
359   int idx=0,maxlen=0,done=0;
360   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
361   char *ret=NULL;
362
363   if(args->pk)
364     keyid_from_pk(args->pk,pk_keyid);
365
366   if(args->sk)
367     keyid_from_sk(args->sk,sk_keyid);
368
369   if(!args->pk && args->sk)
370     keyid_from_sk(args->sk,pk_keyid);
371
372   while(*ch!='\0')
373     {
374       char *str=NULL;
375
376       if(!done)
377         {
378           /* 8192 is way bigger than we'll need here */
379           if(maxlen>=8192)
380             goto fail;
381
382           maxlen+=1024;
383           ret=m_realloc(ret,maxlen);
384         }
385
386       done=0;
387
388       if(*ch=='%')
389         {
390           switch(*(ch+1))
391             {
392             case 's': /* short key id */
393               if(idx+8<maxlen)
394                 {
395                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
396                   idx+=8;
397                   done=1;
398                 }
399               break;
400
401             case 'S': /* long key id */
402               if(idx+16<maxlen)
403                 {
404                   sprintf(&ret[idx],"%08lX%08lX",
405                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
406                   idx+=16;
407                   done=1;
408                 }
409               break;
410
411             case 'k': /* short key id */
412               if(idx+8<maxlen)
413                 {
414                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
415                   idx+=8;
416                   done=1;
417                 }
418               break;
419
420             case 'K': /* long key id */
421               if(idx+16<maxlen)
422                 {
423                   sprintf(&ret[idx],"%08lX%08lX",
424                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
425                   idx+=16;
426                   done=1;
427                 }
428               break;
429
430             case 'f': /* fingerprint */
431               {
432                 byte array[MAX_FINGERPRINT_LEN];
433                 size_t len;
434                 int i;
435
436                 if(args->pk)
437                   fingerprint_from_pk(args->pk,array,&len);
438                 else
439                   memset(array,0,MAX_FINGERPRINT_LEN);
440
441                 if(idx+(len*2)<maxlen)
442                   {
443                     for(i=0;i<len;i++)
444                       {
445                         sprintf(&ret[idx],"%02X",array[i]);
446                         idx+=2;
447                       }
448                     done=1;
449                   }
450               }
451               break;
452
453             case 't': /* e.g. "jpg" */
454               str=image_type_to_string(args->imagetype,0);
455               /* fall through */
456
457             case 'T': /* e.g. "image/jpeg" */
458               if(str==NULL)
459                 str=image_type_to_string(args->imagetype,2);
460
461               if(idx+strlen(str)<maxlen)
462                 {
463                   strcpy(&ret[idx],str);
464                   idx+=strlen(str);
465                   done=1;
466                 }
467               break;
468
469             case '%':
470               if(idx+1<maxlen)
471                 {
472                   ret[idx++]='%';
473                   ret[idx]='\0';
474                   done=1;
475                 }
476               break;
477
478               /* Any unknown %-keys (like %i, %o, %I, and %O) are
479                  passed through for later expansion.  Note this also
480                  handles the case where the last character in the
481                  string is a '%' - the terminating \0 will end up here
482                  and properly terminate the string. */
483             default:
484               if(idx+2<maxlen)
485                 {
486                   ret[idx++]='%';
487                   ret[idx++]=*(ch+1);
488                   ret[idx]='\0';
489                   done=1;
490                 }
491               break;
492               }
493
494           if(done)
495             ch++;
496         }
497       else
498         {
499           if(idx+1<maxlen)
500             {
501               ret[idx++]=*ch;
502               ret[idx]='\0';
503               done=1;
504             }
505         }
506
507       if(done)
508         ch++;
509     }
510
511   return ret;
512
513  fail:
514   m_free(ret);
515   return NULL;
516 }
517
518 int
519 hextobyte( const char *s )
520 {
521     int c;
522
523     if( *s >= '0' && *s <= '9' )
524         c = 16 * (*s - '0');
525     else if( *s >= 'A' && *s <= 'F' )
526         c = 16 * (10 + *s - 'A');
527     else if( *s >= 'a' && *s <= 'f' )
528         c = 16 * (10 + *s - 'a');
529     else
530         return -1;
531     s++;
532     if( *s >= '0' && *s <= '9' )
533         c += *s - '0';
534     else if( *s >= 'A' && *s <= 'F' )
535         c += 10 + *s - 'A';
536     else if( *s >= 'a' && *s <= 'f' )
537         c += 10 + *s - 'a';
538     else
539         return -1;
540     return c;
541 }
542
543 void
544 deprecated_warning(const char *configname,unsigned int configlineno,
545                    const char *option,const char *repl1,const char *repl2)
546 {
547   if(configname)
548     {
549       if(strncmp("--",option,2)==0)
550         option+=2;
551
552       if(strncmp("--",repl1,2)==0)
553         repl1+=2;
554
555       log_info(_("%s:%d: deprecated option \"%s\"\n"),
556                configname,configlineno,option);
557     }
558   else
559     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
560
561   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
562 }
563
564 const char *
565 compress_algo_to_string(int algo)
566 {
567   const char *s="?";
568
569   switch(algo)
570     {
571     case 0:
572       s="Uncompressed";
573       break;
574
575     case 1:
576       s="ZIP";
577       break;
578
579     case 2:
580       s="ZLIB";
581       break;
582     }
583
584   return s;
585 }
586
587 int
588 check_compress_algo(int algo)
589 {
590   if(algo>=0 && algo<=2)
591     return 0;
592
593   return G10ERR_COMPR_ALGO;
594 }