See ChangeLog: Mon Nov 15 21:36:02 CET 1999 Werner Koch
[gnupg.git] / g10 / misc.c
1 /* misc.c -  miscellaneous functions
2  *      Copyright (C) 1998, 1999 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 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
27   #include <asm/sysinfo.h>
28   #include <asm/unistd.h>
29 #endif
30 #ifdef HAVE_SETRLIMIT
31   #include <sys/time.h>
32   #include <sys/resource.h>
33 #endif
34 #include <gcrypt.h>
35 #include "util.h"
36 #include "main.h"
37 #include "options.h"
38 #include "i18n.h"
39
40
41
42 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
43 #warning using trap_unaligned
44 static int
45 setsysinfo(unsigned long op, void *buffer, unsigned long size,
46                      int *start, void *arg, unsigned long flag)
47 {
48     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
49 }
50
51 void
52 trap_unaligned(void)
53 {
54     unsigned int buf[2];
55
56     buf[0] = SSIN_UACPROC;
57     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
58     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
59 }
60 #else
61 void
62 trap_unaligned(void)
63 {  /* dummy */
64 }
65 #endif
66
67
68 void
69 disable_core_dumps()
70 {
71  #ifndef HAVE_DOSISH_SYSTEM
72   #ifdef HAVE_SETRLIMIT
73     struct rlimit limit;
74
75     limit.rlim_cur = 0;
76     limit.rlim_max = 0;
77     if( !setrlimit( RLIMIT_CORE, &limit ) )
78         return;
79     if( errno != EINVAL )
80         log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
81   #endif
82     if( !opt.quiet )
83         log_info(_("WARNING: program may create a core file!\n"));
84  #endif
85 }
86
87
88
89 u16
90 checksum_u16( unsigned n )
91 {
92     u16 a;
93
94     a  = (n >> 8) & 0xff;
95     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM ) {
96        a |= n & 0xff;
97        log_debug("csum_u16 emulated for n=%u\n", n);
98     }
99     else
100        a += n & 0xff;
101     return a;
102 }
103
104 static u16
105 checksum_u16_nobug( unsigned n )
106 {
107     u16 a;
108
109     a  = (n >> 8) & 0xff;
110     a += n & 0xff;
111     return a;
112 }
113
114 u16
115 checksum( byte *p, unsigned n )
116 {
117     u16 a;
118
119     for(a=0; n; n-- )
120         a += *p++;
121     return a;
122 }
123
124 u16
125 checksum_mpi( MPI a )
126 {
127     u16 csum;
128     byte *buffer;
129     unsigned nbytes;
130     unsigned nbits;
131
132     buffer = mpi_get_buffer( a, &nbytes, NULL );
133     /* some versions of gpg encode wrong values for the length of an mpi
134      * so that mpi_get_nbits() which counts the mpi yields another (shorter)
135      * value than the one store with the mpi.  mpi_get_nbit_info() returns
136      * this stored value if it is still available.
137      */
138
139     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM )
140         nbits = 0;
141     else
142         nbits = mpi_get_nbit_info(a);
143     if( !nbits )
144        nbits = mpi_get_nbits(a);
145     csum = checksum_u16( nbits );
146     csum += checksum( buffer, nbytes );
147     m_free( buffer );
148     return csum;
149 }
150
151 /****************
152  * This is the correct function
153  */
154 u16
155 checksum_mpi_counted_nbits( MPI a )
156 {
157     u16 csum;
158     byte *buffer;
159     unsigned nbytes;
160     unsigned nbits;
161
162     buffer = mpi_get_buffer( a, &nbytes, NULL );
163     nbits = mpi_get_nbits(a);
164     mpi_set_nbit_info(a,nbits);
165     csum = checksum_u16_nobug( nbits );
166     csum += checksum( buffer, nbytes );
167     m_free( buffer );
168     return csum;
169 }
170
171
172 u32
173 buffer_to_u32( const byte *buffer )
174 {
175     unsigned long a;
176     a =  *buffer << 24;
177     a |= buffer[1] << 16;
178     a |= buffer[2] << 8;
179     a |= buffer[3];
180     return a;
181 }
182
183
184 static void
185 no_exp_algo(void)
186 {
187     static int did_note = 0;
188
189     if( !did_note ) {
190         did_note = 1;
191         log_info(_("Experimental algorithms should not be used!\n"));
192     }
193 }
194
195 void
196 print_pubkey_algo_note( int algo )
197 {
198     if( algo >= 100 && algo <= 110 )
199         no_exp_algo();
200     else if( is_RSA( algo ) ) {
201         static int did_note = 0;
202
203         if( !did_note ) {
204             did_note = 1;
205             log_info(_("RSA keys are deprecated; please consider "
206                        "creating a new key and use this key in the future\n"));
207         }
208     }
209 }
210
211 void
212 print_cipher_algo_note( int algo )
213 {
214     if( algo >= 100 && algo <= 110 )
215         no_exp_algo();
216     else if(    algo == CIPHER_ALGO_3DES
217              || algo == CIPHER_ALGO_CAST5
218              || algo == CIPHER_ALGO_BLOWFISH
219              || algo == CIPHER_ALGO_TWOFISH
220            )
221         ;
222     else {
223         static int did_note = 0;
224
225         if( !did_note ) {
226             did_note = 1;
227             log_info(_("this cipher algorithm is depreciated; "
228                        "please use a more standard one!\n"));
229         }
230     }
231 }
232
233 void
234 print_digest_algo_note( int algo )
235 {
236     if( algo >= 100 && algo <= 110 )
237         no_exp_algo();
238 }
239
240
241 /****************
242  * Wrapper around the libgcrypt function with addional checks on
243  * openPGP contrainst for the algo ID.
244  */
245 int
246 openpgp_cipher_test_algo( int algo )
247 {
248     if( algo < 0 || algo > 110 )
249         return GCRYERR_INV_CIPHER_ALGO;
250     return gcry_cipher_test_algo(algo);
251 }
252
253 int
254 openpgp_pk_test_algo( int algo, unsigned int usage_flags )
255 {
256     size_t n = usage_flags;
257
258     if( algo < 0 || algo > 110 )
259         return GCRYERR_INV_PK_ALGO;
260     return gcry_pk_algo_info( algo, GCRYCTL_TEST_ALGO, NULL, &n );
261 }
262
263
264 int
265 openpgp_md_test_algo( int algo )
266 {
267     if( algo < 0 || algo > 110 )
268         return GCRYERR_INV_MD_ALGO;
269     return gcry_md_test_algo(algo);
270 }
271
272
273 int
274 pubkey_get_npkey( int algo )
275 {
276     int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, 0 );
277     return n > 0? n : 0;
278 }
279
280 int
281 pubkey_get_nskey( int algo )
282 {
283     int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, 0 );
284     return n > 0? n : 0;
285 }
286
287 int
288 pubkey_get_nsig( int algo )
289 {
290     int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, 0 );
291     return n > 0? n : 0;
292 }
293
294 int
295 pubkey_get_nenc( int algo )
296 {
297     int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, 0 );
298     return n > 0? n : 0;
299 }
300