* misc.c (pull_in_libs): Dead code. Removed.
[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 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
43 static int
44 setsysinfo(unsigned long op, void *buffer, unsigned long size,
45                      int *start, void *arg, unsigned long flag)
46 {
47     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
48 }
49
50 void
51 trap_unaligned(void)
52 {
53     unsigned int buf[2];
54
55     buf[0] = SSIN_UACPROC;
56     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
57     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
58 }
59 #else
60 void
61 trap_unaligned(void)
62 {  /* dummy */
63 }
64 #endif
65
66
67 int
68 disable_core_dumps()
69 {
70 #ifdef HAVE_DOSISH_SYSTEM
71     return 0;
72 #else
73 #ifdef HAVE_SETRLIMIT
74     struct rlimit limit;
75
76     limit.rlim_cur = 0;
77     limit.rlim_max = 0;
78     if( !setrlimit( RLIMIT_CORE, &limit ) )
79         return 0;
80     if( errno != EINVAL && errno != ENOSYS )
81         log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
82 #endif
83     return 1;
84 #endif
85 }
86
87
88
89 u16
90 checksum_u16( unsigned n )
91 {
92     u16 a;
93
94     a  = (n >> 8) & 0xff;
95     a += n & 0xff;
96     return a;
97 }
98
99
100 u16
101 checksum( byte *p, unsigned n )
102 {
103     u16 a;
104
105     for(a=0; n; n-- )
106         a += *p++;
107     return a;
108 }
109
110 u16
111 checksum_mpi( MPI a )
112 {
113     u16 csum;
114     byte *buffer;
115     unsigned nbytes;
116     unsigned nbits;
117
118     buffer = mpi_get_buffer( a, &nbytes, NULL );
119     nbits = mpi_get_nbits(a);
120     csum = checksum_u16( nbits );
121     csum += checksum( buffer, nbytes );
122     m_free( buffer );
123     return csum;
124 }
125
126 u32
127 buffer_to_u32( const byte *buffer )
128 {
129     unsigned long a;
130     a =  *buffer << 24;
131     a |= buffer[1] << 16;
132     a |= buffer[2] << 8;
133     a |= buffer[3];
134     return a;
135 }
136
137
138 static void
139 no_exp_algo(void)
140 {
141     static int did_note = 0;
142
143     if( !did_note ) {
144         did_note = 1;
145         log_info(_("Experimental algorithms should not be used!\n"));
146     }
147 }
148
149 void
150 print_pubkey_algo_note( int algo )
151 {
152     if( algo >= 100 && algo <= 110 )
153         no_exp_algo();
154 }
155
156 void
157 print_cipher_algo_note( int algo )
158 {
159     if( algo >= 100 && algo <= 110 )
160         no_exp_algo();
161     else if(    algo == CIPHER_ALGO_3DES
162              || algo == CIPHER_ALGO_CAST5
163              || algo == CIPHER_ALGO_BLOWFISH
164              || algo == CIPHER_ALGO_TWOFISH
165              || algo == CIPHER_ALGO_RIJNDAEL
166              || algo == CIPHER_ALGO_RIJNDAEL192
167              || algo == CIPHER_ALGO_RIJNDAEL256
168            )
169         ;
170     else {
171         static int did_note = 0;
172
173         if( !did_note ) {
174             did_note = 1;
175             log_info(_("this cipher algorithm is deprecated; "
176                        "please use a more standard one!\n"));
177         }
178     }
179 }
180
181 void
182 print_digest_algo_note( int algo )
183 {
184     if( algo >= 100 && algo <= 110 )
185         no_exp_algo();
186 }
187
188
189 /* Return a string which is used as a kind of process ID */
190 const byte *
191 get_session_marker( size_t *rlen )
192 {
193     static byte marker[SIZEOF_UNSIGNED_LONG*2];
194     static int initialized;
195
196     if ( !initialized ) {
197         volatile ulong aa, bb; /* we really want the uninitialized value */
198         ulong a, b;
199
200         initialized = 1;
201         /* also this marker is guessable it is not easy to use this 
202          * for a faked control packet because an attacker does not
203          * have enough control about the time the verification does 
204          * take place.  Of course, we can add just more random but 
205          * than we need the random generator even for verification
206          * tasks - which does not make sense. */
207         a = aa ^ (ulong)getpid();
208         b = bb ^ (ulong)time(NULL);
209         memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
210         memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
211     }
212     *rlen = sizeof(marker);
213     return marker;
214 }
215
216 /****************
217  * Wrapper around the libgcrypt function with addional checks on
218  * openPGP contraints for the algo ID.
219  */
220 int
221 openpgp_cipher_test_algo( int algo )
222 {
223     if( algo < 0 || algo > 110 )
224         return G10ERR_CIPHER_ALGO;
225     return check_cipher_algo(algo);
226 }
227
228 int
229 openpgp_pk_test_algo( int algo, unsigned int usage_flags )
230 {
231     if( algo < 0 || algo > 110 )
232         return G10ERR_PUBKEY_ALGO;
233     return check_pubkey_algo2( algo, usage_flags );
234 }
235
236 int 
237 openpgp_pk_algo_usage ( int algo )
238 {
239     int use = 0; 
240     
241     /* they are hardwired in gpg 1.0 */
242     switch ( algo ) {    
243       case PUBKEY_ALGO_RSA:
244           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
245           break;
246       case PUBKEY_ALGO_RSA_E:
247           use = PUBKEY_USAGE_ENC;
248           break;
249       case PUBKEY_ALGO_RSA_S:
250           use = PUBKEY_USAGE_SIG;
251           break;
252       case PUBKEY_ALGO_ELGAMAL_E:
253           use = PUBKEY_USAGE_ENC;
254           break;
255       case PUBKEY_ALGO_DSA:  
256           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
257           break;
258       case PUBKEY_ALGO_ELGAMAL:
259           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
260           break;
261       default:
262           break;
263     }
264     return use;
265 }
266
267 int
268 openpgp_md_test_algo( int algo )
269 {
270     if( algo < 0 || algo > 110 )
271         return G10ERR_DIGEST_ALGO;
272     return check_digest_algo(algo);
273 }
274
275 #ifdef USE_IDEA
276 /* Special warning for the IDEA cipher */
277 void
278 idea_cipher_warn(int show)
279 {
280   static int warned=0;
281
282   if(!warned || show)
283     {
284       log_info(_("the IDEA cipher plugin is not present\n"));
285       log_info(_("please see http://www.gnupg.org/why-not-idea.html "
286                  "for more information\n"));
287       warned=1;
288     }
289 }
290 #endif
291
292 /* Expand %-strings.  Returns a string which must be m_freed.  Returns
293    NULL if the string cannot be expanded (too large). */
294 char *
295 pct_expando(const char *string,struct expando_args *args)
296 {
297   const char *ch=string;
298   int idx=0,maxlen=0,done=0;
299   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
300   char *ret=NULL;
301
302   if(args->pk)
303     keyid_from_pk(args->pk,pk_keyid);
304
305   if(args->sk)
306     keyid_from_sk(args->sk,sk_keyid);
307
308   /* This is used so that %k works in photoid command strings in
309      --list-secret-keys (which of course has a sk, but no pk). */
310   if(!args->pk && args->sk)
311     keyid_from_sk(args->sk,pk_keyid);
312
313   while(*ch!='\0')
314     {
315       char *str=NULL;
316
317       if(!done)
318         {
319           /* 8192 is way bigger than we'll need here */
320           if(maxlen>=8192)
321             goto fail;
322
323           maxlen+=1024;
324           ret=m_realloc(ret,maxlen);
325         }
326
327       done=0;
328
329       if(*ch=='%')
330         {
331           switch(*(ch+1))
332             {
333             case 's': /* short key id */
334               if(idx+8<maxlen)
335                 {
336                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
337                   idx+=8;
338                   done=1;
339                 }
340               break;
341
342             case 'S': /* long key id */
343               if(idx+16<maxlen)
344                 {
345                   sprintf(&ret[idx],"%08lX%08lX",
346                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
347                   idx+=16;
348                   done=1;
349                 }
350               break;
351
352             case 'k': /* short key id */
353               if(idx+8<maxlen)
354                 {
355                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
356                   idx+=8;
357                   done=1;
358                 }
359               break;
360
361             case 'K': /* long key id */
362               if(idx+16<maxlen)
363                 {
364                   sprintf(&ret[idx],"%08lX%08lX",
365                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
366                   idx+=16;
367                   done=1;
368                 }
369               break;
370
371             case 'p': /* primary pk fingerprint of a sk */
372             case 'f': /* pk fingerprint */
373             case 'g': /* sk fingerprint */
374               {
375                 byte array[MAX_FINGERPRINT_LEN];
376                 size_t len;
377                 int i;
378
379                 if((*(ch+1))=='p' && args->sk)
380                   {
381                     if(args->sk->is_primary)
382                       fingerprint_from_sk(args->sk,array,&len);
383                     else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
384                       {
385                         PKT_public_key *pk=
386                           m_alloc_clear(sizeof(PKT_public_key));
387
388                         if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
389                           fingerprint_from_pk(pk,array,&len);
390                         else
391                           memset(array,0,(len=MAX_FINGERPRINT_LEN));
392                         free_public_key(pk);
393                       }
394                     else
395                       memset(array,0,(len=MAX_FINGERPRINT_LEN));
396                   }
397                 else if((*(ch+1))=='f' && args->pk)
398                   fingerprint_from_pk(args->pk,array,&len);
399                 else if((*(ch+1))=='g' && args->sk)
400                   fingerprint_from_sk(args->sk,array,&len);
401                 else
402                   memset(array,0,(len=MAX_FINGERPRINT_LEN));
403
404                 if(idx+(len*2)<maxlen)
405                   {
406                     for(i=0;i<len;i++)
407                       {
408                         sprintf(&ret[idx],"%02X",array[i]);
409                         idx+=2;
410                       }
411                     done=1;
412                   }
413               }
414               break;
415
416             case 't': /* e.g. "jpg" */
417               str=image_type_to_string(args->imagetype,0);
418               /* fall through */
419
420             case 'T': /* e.g. "image/jpeg" */
421               if(str==NULL)
422                 str=image_type_to_string(args->imagetype,2);
423
424               if(idx+strlen(str)<maxlen)
425                 {
426                   strcpy(&ret[idx],str);
427                   idx+=strlen(str);
428                   done=1;
429                 }
430               break;
431
432             case '%':
433               if(idx+1<maxlen)
434                 {
435                   ret[idx++]='%';
436                   ret[idx]='\0';
437                   done=1;
438                 }
439               break;
440
441               /* Any unknown %-keys (like %i, %o, %I, and %O) are
442                  passed through for later expansion.  Note this also
443                  handles the case where the last character in the
444                  string is a '%' - the terminating \0 will end up here
445                  and properly terminate the string. */
446             default:
447               if(idx+2<maxlen)
448                 {
449                   ret[idx++]='%';
450                   ret[idx++]=*(ch+1);
451                   ret[idx]='\0';
452                   done=1;
453                 }
454               break;
455               }
456
457           if(done)
458             ch++;
459         }
460       else
461         {
462           if(idx+1<maxlen)
463             {
464               ret[idx++]=*ch;
465               ret[idx]='\0';
466               done=1;
467             }
468         }
469
470       if(done)
471         ch++;
472     }
473
474   return ret;
475
476  fail:
477   m_free(ret);
478   return NULL;
479 }
480
481 int
482 hextobyte( const char *s )
483 {
484     int c;
485
486     if( *s >= '0' && *s <= '9' )
487         c = 16 * (*s - '0');
488     else if( *s >= 'A' && *s <= 'F' )
489         c = 16 * (10 + *s - 'A');
490     else if( *s >= 'a' && *s <= 'f' )
491         c = 16 * (10 + *s - 'a');
492     else
493         return -1;
494     s++;
495     if( *s >= '0' && *s <= '9' )
496         c += *s - '0';
497     else if( *s >= 'A' && *s <= 'F' )
498         c += 10 + *s - 'A';
499     else if( *s >= 'a' && *s <= 'f' )
500         c += 10 + *s - 'a';
501     else
502         return -1;
503     return c;
504 }
505
506 void
507 deprecated_warning(const char *configname,unsigned int configlineno,
508                    const char *option,const char *repl1,const char *repl2)
509 {
510   if(configname)
511     {
512       if(strncmp("--",option,2)==0)
513         option+=2;
514
515       if(strncmp("--",repl1,2)==0)
516         repl1+=2;
517
518       log_info(_("%s:%d: deprecated option \"%s\"\n"),
519                configname,configlineno,option);
520     }
521   else
522     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
523
524   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
525 }
526
527 const char *
528 compress_algo_to_string(int algo)
529 {
530   const char *s="?";
531
532   switch(algo)
533     {
534     case COMPRESS_ALGO_NONE:
535       s=_("Uncompressed");
536       break;
537
538     case COMPRESS_ALGO_ZIP:
539       s="ZIP";
540       break;
541
542     case COMPRESS_ALGO_ZLIB:
543       s="ZLIB";
544       break;
545
546 #ifdef HAVE_BZIP2
547     case COMPRESS_ALGO_BZIP2:
548       s="BZIP2";
549       break;
550 #endif
551     }
552
553   return s;
554 }
555
556 int
557 string_to_compress_algo(const char *string)
558 {
559   /* NOTE TO TRANSLATOR: See doc/TRANSLATE about this string. */
560   if(match_multistr(_("uncompressed|none"),string))
561     return 0;
562   else if(ascii_strcasecmp(string,"uncompressed")==0)
563     return 0;
564   else if(ascii_strcasecmp(string,"none")==0)
565     return 0;
566   else if(ascii_strcasecmp(string,"zip")==0)
567     return 1;
568   else if(ascii_strcasecmp(string,"zlib")==0)
569     return 2;
570 #ifdef HAVE_BZIP2
571   else if(ascii_strcasecmp(string,"bzip2")==0)
572     return 3;
573 #endif
574   else if(ascii_strcasecmp(string,"z0")==0)
575     return 0;
576   else if(ascii_strcasecmp(string,"z1")==0)
577     return 1;
578   else if(ascii_strcasecmp(string,"z2")==0)
579     return 2;
580 #ifdef HAVE_BZIP2
581   else if(ascii_strcasecmp(string,"z3")==0)
582     return 3;
583 #endif
584   else
585     return -1;
586 }
587
588 int
589 check_compress_algo(int algo)
590 {
591 #ifdef HAVE_BZIP2
592   if(algo>=0 && algo<=3)
593     return 0;
594 #else
595   if(algo>=0 && algo<=2)
596     return 0;
597 #endif
598
599   return G10ERR_COMPR_ALGO;
600 }
601
602 int
603 default_cipher_algo(void)
604 {
605   if(opt.def_cipher_algo)
606     return opt.def_cipher_algo;
607   else if(opt.personal_cipher_prefs)
608     return opt.personal_cipher_prefs[0].value;
609   else
610     return opt.s2k_cipher_algo;
611 }
612
613 /* There is no default_digest_algo function, but see
614    sign.c:hash_for() */
615
616 int
617 default_compress_algo(void)
618 {
619   if(opt.compress_algo!=-1)
620     return opt.compress_algo;
621   else if(opt.personal_compress_prefs)
622     return opt.personal_compress_prefs[0].value;
623   else
624     return DEFAULT_COMPRESS_ALGO;
625 }
626
627 const char *
628 compliance_option_string(void)
629 {
630   switch(opt.compliance)
631     {
632     case CO_RFC2440:
633       return "--openpgp";
634     case CO_PGP2:
635       return "--pgp2";
636     case CO_PGP6:
637       return "--pgp6";
638     case CO_PGP7:
639       return "--pgp7";
640     case CO_PGP8:
641       return "--pgp8";
642     default:
643       return "???";
644     }
645 }
646
647 static const char *
648 compliance_string(void)
649 {
650   switch(opt.compliance)
651     {
652     case CO_RFC2440:
653       return "OpenPGP";
654     case CO_PGP2:
655       return "PGP 2.x";
656     case CO_PGP6:
657       return "PGP 6.x";
658     case CO_PGP7:
659       return "PGP 7.x";
660     case CO_PGP8:
661       return "PGP 8.x";
662     default:
663       return "???";
664     }
665 }
666
667 void
668 compliance_failure(void)
669 {
670   log_info(_("this message may not be usable by %s\n"),compliance_string());
671   opt.compliance=CO_GNUPG;
672 }
673
674 int
675 parse_options(char *str,unsigned int *options,
676               struct parse_options *opts,int noisy)
677 {
678   char *tok;
679
680   while((tok=strsep(&str," ,")))
681     {
682       int i,rev=0;
683       char *otok=tok;
684
685       if(tok[0]=='\0')
686         continue;
687
688       if(ascii_strncasecmp("no-",tok,3)==0)
689         {
690           rev=1;
691           tok+=3;
692         }
693
694       for(i=0;opts[i].name;i++)
695         {
696           size_t toklen=strlen(tok);
697
698           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
699             {
700               /* We have a match, but it might be incomplete */
701               if(toklen!=strlen(opts[i].name))
702                 {
703                   int j;
704
705                   for(j=i+1;opts[j].name;j++)
706                     {
707                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
708                         {
709                           if(noisy)
710                             log_info(_("ambiguous option `%s'\n"),otok);
711                           return 0;
712                         }
713                     }
714                 }
715
716               if(rev)
717                 *options&=~opts[i].bit;
718               else
719                 *options|=opts[i].bit;
720               break;
721             }
722         }
723
724       if(!opts[i].name)
725         {
726           if(noisy)
727             log_info(_("unknown option `%s'\n"),otok);
728           return 0;
729         }
730     }
731
732   return 1;
733 }