1 /* misc.c - miscellaneous functions
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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
27 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
28 #include <asm/sysinfo.h>
29 #include <asm/unistd.h>
34 #include <sys/resource.h>
43 const char *g10m_revision_string(int);
44 const char *g10c_revision_string(int);
45 const char *g10u_revision_string(int);
53 g10m_revision_string(0);
54 g10c_revision_string(0);
55 g10u_revision_string(0);
59 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
61 setsysinfo(unsigned long op, void *buffer, unsigned long size,
62 int *start, void *arg, unsigned long flag)
64 return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
72 buf[0] = SSIN_UACPROC;
73 buf[1] = UAC_SIGBUS | UAC_NOPRINT;
74 setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
87 #ifdef HAVE_DOSISH_SYSTEM
95 if( !setrlimit( RLIMIT_CORE, &limit ) )
97 if( errno != EINVAL && errno != ENOSYS )
98 log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
107 checksum_u16( unsigned n )
112 if( opt.emulate_bugs & EMUBUG_GPGCHKSUM ) {
114 log_debug("csum_u16 emulated for n=%u\n", n);
122 checksum_u16_nobug( unsigned n )
132 checksum( byte *p, unsigned n )
142 checksum_mpi( MPI a )
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.
156 if( opt.emulate_bugs & EMUBUG_GPGCHKSUM )
159 nbits = mpi_get_nbit_info(a);
161 nbits = mpi_get_nbits(a);
162 csum = checksum_u16( nbits );
163 csum += checksum( buffer, nbytes );
169 * This is the correct function
172 checksum_mpi_counted_nbits( MPI a )
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 );
190 buffer_to_u32( const byte *buffer )
194 a |= buffer[1] << 16;
204 static int did_note = 0;
208 log_info(_("Experimental algorithms should not be used!\n"));
213 print_pubkey_algo_note( int algo )
215 if( algo >= 100 && algo <= 110 )
220 print_cipher_algo_note( int algo )
222 if( algo >= 100 && algo <= 110 )
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
234 static int did_note = 0;
238 log_info(_("this cipher algorithm is deprecated; "
239 "please use a more standard one!\n"));
245 print_digest_algo_note( int algo )
247 if( algo >= 100 && algo <= 110 )
252 /* Return a string which is used as a kind of process ID */
254 get_session_marker( size_t *rlen )
256 static byte marker[SIZEOF_UNSIGNED_LONG*2];
257 static int initialized;
259 if ( !initialized ) {
260 volatile ulong aa, bb; /* we really want the uninitialized value */
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 );
275 *rlen = sizeof(marker);
280 * Wrapper around the libgcrypt function with addional checks on
281 * openPGP contraints for the algo ID.
284 openpgp_cipher_test_algo( int algo )
286 if( algo < 0 || algo > 110 )
287 return G10ERR_CIPHER_ALGO;
288 return check_cipher_algo(algo);
292 openpgp_pk_test_algo( int algo, unsigned int usage_flags )
294 if( algo < 0 || algo > 110 )
295 return G10ERR_PUBKEY_ALGO;
296 return check_pubkey_algo2( algo, usage_flags );
300 openpgp_pk_algo_usage ( int algo )
304 /* they are hardwired in gpg 1.0 */
306 case PUBKEY_ALGO_RSA:
307 use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
309 case PUBKEY_ALGO_RSA_E:
310 use = PUBKEY_USAGE_ENC;
312 case PUBKEY_ALGO_RSA_S:
313 use = PUBKEY_USAGE_SIG;
315 case PUBKEY_ALGO_ELGAMAL_E:
316 use = PUBKEY_USAGE_ENC;
318 case PUBKEY_ALGO_DSA:
319 use = PUBKEY_USAGE_SIG;
321 case PUBKEY_ALGO_ELGAMAL:
322 use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
331 openpgp_md_test_algo( int algo )
333 if( algo < 0 || algo > 110 )
334 return G10ERR_DIGEST_ALGO;
335 return check_digest_algo(algo);
338 /* Special warning for the IDEA cipher */
340 idea_cipher_warn(int show)
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"));
353 /* Expand %-strings. Returns a string which must be m_freed. Returns
354 NULL if the string cannot be expanded (too large). */
356 pct_expando(const char *string,struct expando_args *args)
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};
364 keyid_from_pk(args->pk,pk_keyid);
367 keyid_from_sk(args->sk,sk_keyid);
369 if(!args->pk && args->sk)
370 keyid_from_sk(args->sk,pk_keyid);
378 /* 8192 is way bigger than we'll need here */
383 ret=m_realloc(ret,maxlen);
392 case 's': /* short key id */
395 sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
401 case 'S': /* long key id */
404 sprintf(&ret[idx],"%08lX%08lX",
405 (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
411 case 'k': /* short key id */
414 sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
420 case 'K': /* long key id */
423 sprintf(&ret[idx],"%08lX%08lX",
424 (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
430 case 'f': /* fingerprint */
432 byte array[MAX_FINGERPRINT_LEN];
437 fingerprint_from_pk(args->pk,array,&len);
439 memset(array,0,MAX_FINGERPRINT_LEN);
441 if(idx+(len*2)<maxlen)
445 sprintf(&ret[idx],"%02X",array[i]);
453 case 't': /* e.g. "jpg" */
454 str=image_type_to_string(args->imagetype,0);
457 case 'T': /* e.g. "image/jpeg" */
459 str=image_type_to_string(args->imagetype,2);
461 if(idx+strlen(str)<maxlen)
463 strcpy(&ret[idx],str);
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. */
519 hextobyte( const char *s )
523 if( *s >= '0' && *s <= '9' )
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');
532 if( *s >= '0' && *s <= '9' )
534 else if( *s >= 'A' && *s <= 'F' )
536 else if( *s >= 'a' && *s <= 'f' )
544 deprecated_warning(const char *configname,unsigned int configlineno,
545 const char *option,const char *repl1,const char *repl2)
549 if(strncmp("--",option,2)==0)
552 if(strncmp("--",repl1,2)==0)
555 log_info(_("%s:%d: deprecated option \"%s\"\n"),
556 configname,configlineno,option);
559 log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
561 log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
565 compress_algo_to_string(int algo)
588 check_compress_algo(int algo)
590 if(algo>=0 && algo<=2)
593 return G10ERR_COMPR_ALGO;