1 /* misc.c - miscellaneous functions
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2003 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
29 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
30 #include <asm/sysinfo.h>
31 #include <asm/unistd.h>
36 #include <sys/resource.h>
46 #define MAX_EXTERN_MPI_BITS 16384
49 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
51 setsysinfo(unsigned long op
, void *buffer
, unsigned long size
,
52 int *start
, void *arg
, unsigned long flag
)
54 return syscall(__NR_osf_setsysinfo
, op
, buffer
, size
, start
, arg
, flag
);
62 buf
[0] = SSIN_UACPROC
;
63 buf
[1] = UAC_SIGBUS
| UAC_NOPRINT
;
64 setsysinfo(SSI_NVPAIRS
, buf
, 1, 0, 0, 0);
77 #ifdef HAVE_DOSISH_SYSTEM
85 if( !setrlimit( RLIMIT_CORE
, &limit
) )
87 if( errno
!= EINVAL
&& errno
!= ENOSYS
)
88 log_fatal(_("can't disable core dumps: %s\n"), strerror(errno
) );
97 checksum_u16( unsigned n
)
108 checksum( byte
*p
, unsigned n
)
118 checksum_mpi( gcry_mpi_t a
)
125 rc
= gcry_mpi_print( GCRYMPI_FMT_PGP
, NULL
, 0, &nbytes
, a
);
128 /* fixme: for numbers not in secure memory we should use a stack
129 * based buffer and only allocate a larger one if mpi_print return
131 buffer
= gcry_is_secure(a
)? gcry_xmalloc_secure(nbytes
):gcry_xmalloc(nbytes
);
132 rc
= gcry_mpi_print (GCRYMPI_FMT_PGP
, buffer
, nbytes
, NULL
, a
);
135 csum
= checksum (buffer
, nbytes
);
141 buffer_to_u32( const byte
*buffer
)
145 a
|= buffer
[1] << 16;
155 static int did_note
= 0;
159 log_info(_("Experimental algorithms should not be used!\n"));
164 print_pubkey_algo_note( int algo
)
166 if( algo
>= 100 && algo
<= 110 )
171 print_cipher_algo_note( int algo
)
173 if( algo
>= 100 && algo
<= 110 )
175 else if( algo
== CIPHER_ALGO_3DES
176 || algo
== CIPHER_ALGO_CAST5
177 || algo
== CIPHER_ALGO_BLOWFISH
178 || algo
== CIPHER_ALGO_TWOFISH
179 || algo
== CIPHER_ALGO_RIJNDAEL
180 || algo
== CIPHER_ALGO_RIJNDAEL192
181 || algo
== CIPHER_ALGO_RIJNDAEL256
185 static int did_note
= 0;
189 log_info(_("this cipher algorithm is deprecated; "
190 "please use a more standard one!\n"));
196 print_digest_algo_note( int algo
)
198 if( algo
>= 100 && algo
<= 110 )
203 /* Return a string which is used as a kind of process ID */
205 get_session_marker( size_t *rlen
)
207 static byte marker
[SIZEOF_UNSIGNED_LONG
*2];
208 static int initialized
;
210 if ( !initialized
) {
211 volatile ulong aa
, bb
; /* we really want the uninitialized value */
215 /* also this marker is guessable it is not easy to use this
216 * for a faked control packet because an attacker does not
217 * have enough control about the time the verification does
218 * take place. Of course, we can add just more random but
219 * than we need the random generator even for verification
220 * tasks - which does not make sense. */
221 a
= aa
^ (ulong
)getpid();
222 b
= bb
^ (ulong
)time(NULL
);
223 memcpy( marker
, &a
, SIZEOF_UNSIGNED_LONG
);
224 memcpy( marker
+SIZEOF_UNSIGNED_LONG
, &b
, SIZEOF_UNSIGNED_LONG
);
226 *rlen
= sizeof(marker
);
231 * Wrapper around the libgcrypt function with addional checks on
232 * openPGP contraints for the algo ID.
235 openpgp_cipher_test_algo( int algo
)
237 if( algo
< 0 || algo
> 110 )
238 return GPG_ERR_CIPHER_ALGO
;
239 return gcry_cipher_test_algo (algo
);
243 openpgp_pk_test_algo( int algo
, unsigned int usage_flags
)
245 size_t value
= usage_flags
;
247 if (algo
== GCRY_PK_ELG_E
)
250 #warning need to handle the usage here?
252 if (algo
< 0 || algo
> 110)
253 return GPG_ERR_PUBKEY_ALGO
;
254 return gcry_pk_algo_info (algo
, GCRYCTL_TEST_ALGO
, NULL
, &value
);
258 openpgp_pk_algo_usage ( int algo
)
262 /* they are hardwired in gpg 1.0 */
264 case PUBKEY_ALGO_RSA
:
265 use
= PUBKEY_USAGE_SIG
| PUBKEY_USAGE_ENC
| PUBKEY_USAGE_AUTH
;
267 case PUBKEY_ALGO_RSA_E
:
268 use
= PUBKEY_USAGE_ENC
;
270 case PUBKEY_ALGO_RSA_S
:
271 use
= PUBKEY_USAGE_SIG
;
273 case PUBKEY_ALGO_ELGAMAL_E
:
274 use
= PUBKEY_USAGE_ENC
;
276 case PUBKEY_ALGO_DSA
:
277 use
= PUBKEY_USAGE_SIG
| PUBKEY_USAGE_AUTH
;
279 case PUBKEY_ALGO_ELGAMAL
:
280 use
= PUBKEY_USAGE_SIG
| PUBKEY_USAGE_ENC
| PUBKEY_USAGE_AUTH
;
289 openpgp_md_test_algo( int algo
)
291 if( algo
< 0 || algo
> 110 )
292 return GPG_ERR_DIGEST_ALGO
;
293 return gcry_md_test_algo (algo
);
297 openpgp_md_map_name (const char *string
)
299 int i
= gcry_md_map_name (string
);
301 if (!i
&& (string
[0]=='H' || string
[0]=='h'))
302 { /* Didn't find it, so try the Hx format */
308 val
=strtol(string
,&endptr
,10);
309 if (*string
!='\0' && *endptr
=='\0' && !openpgp_md_test_algo(val
))
312 return i
< 0 || i
> 110? 0 : i
;
316 openpgp_cipher_map_name (const char *string
)
318 int i
= gcry_cipher_map_name (string
);
320 if (!i
&& (string
[0]=='S' || string
[0]=='s'))
321 { /* Didn't find it, so try the Sx format */
327 val
=strtol(string
,&endptr
,10);
328 if (*string
!='\0' && *endptr
=='\0' && !openpgp_cipher_test_algo(val
))
331 return i
< 0 || i
> 110? 0 : i
;
335 openpgp_pk_map_name (const char *string
)
337 int i
= gcry_pk_map_name (string
);
338 return i
< 0 || i
> 110? 0 : i
;
342 /* Special warning for the IDEA cipher */
344 idea_cipher_warn(int show
)
350 log_info(_("the IDEA cipher plugin is not present\n"));
351 log_info(_("please see http://www.gnupg.org/why-not-idea.html "
352 "for more information\n"));
358 /* Expand %-strings. Returns a string which must be m_freed. Returns
359 NULL if the string cannot be expanded (too large). */
361 pct_expando(const char *string
,struct expando_args
*args
)
363 const char *ch
=string
;
364 int idx
=0,maxlen
=0,done
=0;
365 u32 pk_keyid
[2]={0,0},sk_keyid
[2]={0,0};
369 keyid_from_pk(args
->pk
,pk_keyid
);
372 keyid_from_sk(args
->sk
,sk_keyid
);
374 /* This is used so that %k works in photoid command strings in
375 --list-secret-keys (which of course has a sk, but no pk). */
376 if(!args
->pk
&& args
->sk
)
377 keyid_from_sk(args
->sk
,pk_keyid
);
385 /* 8192 is way bigger than we'll need here */
390 ret
= xrealloc(ret
,maxlen
);
399 case 's': /* short key id */
402 sprintf(&ret
[idx
],"%08lX",(ulong
)sk_keyid
[1]);
408 case 'S': /* long key id */
411 sprintf(&ret
[idx
],"%08lX%08lX",
412 (ulong
)sk_keyid
[0],(ulong
)sk_keyid
[1]);
418 case 'k': /* short key id */
421 sprintf(&ret
[idx
],"%08lX",(ulong
)pk_keyid
[1]);
427 case 'K': /* long key id */
430 sprintf(&ret
[idx
],"%08lX%08lX",
431 (ulong
)pk_keyid
[0],(ulong
)pk_keyid
[1]);
437 case 'p': /* primary pk fingerprint of a sk */
438 case 'f': /* pk fingerprint */
439 case 'g': /* sk fingerprint */
441 byte array
[MAX_FINGERPRINT_LEN
];
445 if( ch
[1]=='p' && args
->sk
)
447 if(args
->sk
->is_primary
)
448 fingerprint_from_sk(args
->sk
,array
,&len
);
449 else if(args
->sk
->main_keyid
[0] || args
->sk
->main_keyid
[1])
451 PKT_public_key
*pk
= xcalloc(1, sizeof(PKT_public_key
));
453 if(get_pubkey_fast(pk
,args
->sk
->main_keyid
)==0)
454 fingerprint_from_pk(pk
,array
,&len
);
456 memset(array
,0,(len
=MAX_FINGERPRINT_LEN
));
460 memset(array
,0,(len
=MAX_FINGERPRINT_LEN
));
462 else if( ch
[1]=='f' && args
->pk
)
463 fingerprint_from_pk(args
->pk
,array
,&len
);
464 else if( ch
[1]=='g' && args
->sk
)
465 fingerprint_from_sk(args
->sk
,array
,&len
);
467 memset(array
, 0, (len
=MAX_FINGERPRINT_LEN
));
469 if(idx
+(len
*2)<maxlen
)
473 sprintf(&ret
[idx
],"%02X",array
[i
]);
481 case 't': /* e.g. "jpg" */
482 str
=image_type_to_string(args
->imagetype
,0);
485 case 'T': /* e.g. "image/jpeg" */
487 str
=image_type_to_string(args
->imagetype
,2);
489 if(idx
+strlen(str
)<maxlen
)
491 strcpy(&ret
[idx
],str
);
506 /* Any unknown %-keys (like %i, %o, %I, and %O) are
507 passed through for later expansion. Note this also
508 handles the case where the last character in the
509 string is a '%' - the terminating \0 will end up here
510 and properly terminate the string. */
547 hextobyte( const char *s
)
551 if( *s
>= '0' && *s
<= '9' )
553 else if( *s
>= 'A' && *s
<= 'F' )
554 c
= 16 * (10 + *s
- 'A');
555 else if( *s
>= 'a' && *s
<= 'f' )
556 c
= 16 * (10 + *s
- 'a');
560 if( *s
>= '0' && *s
<= '9' )
562 else if( *s
>= 'A' && *s
<= 'F' )
564 else if( *s
>= 'a' && *s
<= 'f' )
572 deprecated_warning(const char *configname
,unsigned int configlineno
,
573 const char *option
,const char *repl1
,const char *repl2
)
577 if(strncmp("--",option
,2)==0)
580 if(strncmp("--",repl1
,2)==0)
583 log_info(_("%s:%d: deprecated option \"%s\"\n"),
584 configname
,configlineno
,option
);
587 log_info(_("WARNING: \"%s\" is a deprecated option\n"),option
);
589 log_info(_("please use \"%s%s\" instead\n"),repl1
,repl2
);
593 compress_algo_to_string(int algo
)
616 string_to_compress_algo(const char *string
)
618 if(ascii_strcasecmp(string
,"uncompressed")==0)
620 else if(ascii_strcasecmp(string
,"zip")==0)
622 else if(ascii_strcasecmp(string
,"zlib")==0)
624 else if(ascii_strcasecmp(string
,"z0")==0)
626 else if(ascii_strcasecmp(string
,"z1")==0)
628 else if(ascii_strcasecmp(string
,"z2")==0)
635 check_compress_algo(int algo
)
637 if(algo
>=0 && algo
<=2)
640 return GPG_ERR_COMPR_ALGO
;
644 default_cipher_algo(void)
646 if(opt
.def_cipher_algo
)
647 return opt
.def_cipher_algo
;
648 else if(opt
.personal_cipher_prefs
)
649 return opt
.personal_cipher_prefs
[0].value
;
651 return opt
.s2k_cipher_algo
;
654 /* There is no default_digest_algo function, but see
658 default_compress_algo(void)
660 if(opt
.def_compress_algo
!=-1)
661 return opt
.def_compress_algo
;
662 else if(opt
.personal_compress_prefs
)
663 return opt
.personal_compress_prefs
[0].value
;
665 return DEFAULT_COMPRESS_ALGO
;
669 compliance_option_string(void)
671 switch(opt
.compliance
)
689 compliance_string(void)
691 switch(opt
.compliance
)
709 compliance_failure(void)
711 log_info(_("this message may not be usable by %s\n"),compliance_string());
712 opt
.compliance
=CO_GNUPG
;
716 parse_options(char *str
,unsigned int *options
,struct parse_options
*opts
)
720 while((tok
=strsep(&str
," ,")))
727 if(ascii_strncasecmp("no-",tok
,3)==0)
733 for(i
=0;opts
[i
].name
;i
++)
735 if(ascii_strcasecmp(opts
[i
].name
,tok
)==0)
738 *options
&=~opts
[i
].bit
;
740 *options
|=opts
[i
].bit
;
754 /* Temporary helper. */
756 pubkey_get_npkey( int algo
)
760 if (algo
== GCRY_PK_ELG_E
)
762 if (gcry_pk_algo_info( algo
, GCRYCTL_GET_ALGO_NPKEY
, NULL
, &n
))
767 /* Temporary helper. */
769 pubkey_get_nskey( int algo
)
773 if (algo
== GCRY_PK_ELG_E
)
775 if (gcry_pk_algo_info( algo
, GCRYCTL_GET_ALGO_NSKEY
, NULL
, &n
))
780 /* Temporary helper. */
782 pubkey_get_nsig( int algo
)
786 if (algo
== GCRY_PK_ELG_E
)
788 if (gcry_pk_algo_info( algo
, GCRYCTL_GET_ALGO_NSIGN
, NULL
, &n
))
793 /* Temporary helper. */
795 pubkey_get_nenc( int algo
)
799 if (algo
== GCRY_PK_ELG_E
)
801 if (gcry_pk_algo_info( algo
, GCRYCTL_GET_ALGO_NENCR
, NULL
, &n
))
807 /* Temporary helper. */
809 pubkey_nbits( int algo
, gcry_mpi_t
*key
)
814 if( algo
== GCRY_PK_DSA
) {
815 rc
= gcry_sexp_build ( &sexp
, NULL
,
816 "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
817 key
[0], key
[1], key
[2], key
[3] );
819 else if( algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
) {
820 rc
= gcry_sexp_build ( &sexp
, NULL
,
821 "(public-key(elg(p%m)(g%m)(y%m)))",
822 key
[0], key
[1], key
[2] );
824 else if( algo
== GCRY_PK_RSA
) {
825 rc
= gcry_sexp_build ( &sexp
, NULL
,
826 "(public-key(rsa(n%m)(e%m)))",
835 nbits
= gcry_pk_get_nbits( sexp
);
836 gcry_sexp_release( sexp
);
841 /* MPI helper functions. */
845 * write an mpi to out.
848 mpi_write( iobuf_t out
, gcry_mpi_t a
)
850 char buffer
[(MAX_EXTERN_MPI_BITS
+7)/8];
854 nbytes
= (MAX_EXTERN_MPI_BITS
+7)/8;
855 rc
= gcry_mpi_print (GCRYMPI_FMT_PGP
, buffer
, nbytes
, &nbytes
, a
);
857 rc
= iobuf_write( out
, buffer
, nbytes
);
863 * Writyeg a MPI to out, but in this case it is an opaque one,
864 * s used vor v3 protected keys.
867 mpi_write_opaque( iobuf_t out
, gcry_mpi_t a
)
869 size_t nbytes
, nbits
;
873 assert( gcry_mpi_get_flag( a
, GCRYMPI_FLAG_OPAQUE
) );
874 p
= gcry_mpi_get_opaque( a
, &nbits
);
875 nbytes
= (nbits
+7) / 8;
876 iobuf_put( out
, nbits
>> 8 );
877 iobuf_put( out
, nbits
);
878 rc
= iobuf_write( out
, p
, nbytes
);
884 * Read an external representation of an mpi and return the MPI
885 * The external format is a 16 bit unsigned value stored in network byte order,
886 * giving the number of bits for the following integer. The integer is stored
887 * with MSB first (left padded with zeroes to align on a byte boundary).
890 mpi_read(iobuf_t inp
, unsigned int *ret_nread
, int secure
)
893 unsigned int nbits
, nbytes
, nread
=0;
898 if( (c
= c1
= iobuf_get(inp
)) == -1 )
901 if( (c
= c2
= iobuf_get(inp
)) == -1 )
904 if( nbits
> MAX_EXTERN_MPI_BITS
) {
905 log_error("mpi too large (%u bits)\n", nbits
);
909 nbytes
= (nbits
+7) / 8;
910 buf
= secure
? gcry_xmalloc_secure( nbytes
+2 ) : gcry_xmalloc( nbytes
+2 );
914 for( i
=0 ; i
< nbytes
; i
++ ) {
915 p
[i
+2] = iobuf_get(inp
) & 0xff;
919 if( gcry_mpi_scan( &a
, GCRYMPI_FMT_PGP
, buf
, nread
, &nread
) )
924 if( nread
> *ret_nread
)
925 log_bug("mpi larger than packet");
932 * Same as mpi_read but the value is stored as an opaque MPI.
933 * This function is used to read encrypted MPI of v3 packets.
936 mpi_read_opaque(iobuf_t inp
, unsigned *ret_nread
)
939 unsigned nbits
, nbytes
, nread
=0;
944 if( (c
= c1
= iobuf_get(inp
)) == -1 )
947 if( (c
= c2
= iobuf_get(inp
)) == -1 )
950 if( nbits
> MAX_EXTERN_MPI_BITS
) {
951 log_error("mpi too large (%u bits)\n", nbits
);
955 nbytes
= (nbits
+7) / 8;
956 buf
= gcry_xmalloc( nbytes
);
958 for( i
=0 ; i
< nbytes
; i
++ ) {
959 p
[i
] = iobuf_get(inp
) & 0xff;
962 a
= gcry_mpi_set_opaque(NULL
, buf
, nbits
);
967 if( nread
> *ret_nread
)
968 log_bug("mpi larger than packet");
976 mpi_print( FILE *fp
, gcry_mpi_t a
, int mode
)
981 return fprintf(fp
, "[MPI_NULL]");
984 n1
= gcry_mpi_get_nbits(a
);
985 n
+= fprintf(fp
, "[%u bits]", n1
);
989 unsigned char *buffer
;
991 rc
= gcry_mpi_aprint( GCRYMPI_FMT_HEX
, &buffer
, NULL
, a
);