1
/* misc.c - miscellaneous functions
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
3
* 2003 Free Software Foundation, Inc.
1
/* misc.c - miscellaneous functions
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
* 2005, 2006, 2007 Free Software Foundation, Inc.
5
5
* This file is part of GnuPG.
7
7
* GnuPG is free software; you can redistribute it and/or modify
8
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
9
* the Free Software Foundation; either version 3 of the License, or
10
10
* (at your option) any later version.
12
12
* GnuPG is distributed in the hope that it will be useful,
35
33
#include <sys/time.h>
36
34
#include <sys/resource.h>
36
#ifdef ENABLE_SELINUX_HACKS
40
#ifdef HAVE_W32_SYSTEM
46
#define CSIDL_APPDATA 0x001a
48
#ifndef CSIDL_LOCAL_APPDATA
49
#define CSIDL_LOCAL_APPDATA 0x001c
51
#ifndef CSIDL_FLAG_CREATE
52
#define CSIDL_FLAG_CREATE 0x8000
54
#endif /*HAVE_W32_SYSTEM*/
57
#ifdef HAVE_W32_SYSTEM
59
#endif /*HAVE_W32_SYSTEM*/
42
62
#include "photoid.h"
43
63
#include "options.h"
64
#include "call-agent.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) );
69
string_count_chr (const char *string, int c)
73
for (count=0; *string; string++ )
81
#ifdef ENABLE_SELINUX_HACKS
82
/* A object and a global variable to keep track of files marked as
84
struct secured_file_item
86
struct secured_file_item *next;
90
static struct secured_file_item *secured_files;
91
#endif /*ENABLE_SELINUX_HACKS*/
96
/* For the sake of SELinux we want to restrict access through gpg to
97
certain files we keep under our own control. This function
98
registers such a file and is_secured_file may then be used to
99
check whether a file has ben registered as secured. */
101
register_secured_file (const char *fname)
103
#ifdef ENABLE_SELINUX_HACKS
105
struct secured_file_item *sf;
107
/* Note that we stop immediatley if something goes wrong here. */
108
if (stat (fname, &buf))
109
log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname,
110
"register_secured_file", strerror (errno));
111
/* log_debug ("registering `%s' i=%lu.%lu\n", fname, */
112
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
113
for (sf=secured_files; sf; sf = sf->next)
115
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
116
return; /* Already registered. */
119
sf = xmalloc (sizeof *sf);
120
sf->ino = buf.st_ino;
121
sf->dev = buf.st_dev;
122
sf->next = secured_files;
124
#endif /*ENABLE_SELINUX_HACKS*/
127
/* Remove a file registered as secure. */
129
unregister_secured_file (const char *fname)
131
#ifdef ENABLE_SELINUX_HACKS
133
struct secured_file_item *sf, *sfprev;
135
if (stat (fname, &buf))
137
log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
138
"unregister_secured_file", strerror (errno));
141
/* log_debug ("unregistering `%s' i=%lu.%lu\n", fname, */
142
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
143
for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
145
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
148
sfprev->next = sf->next;
150
secured_files = sf->next;
155
#endif /*ENABLE_SELINUX_HACKS*/
158
/* Return true if FD is corresponds to a secured file. Using -1 for
159
FS is allowed and will return false. */
161
is_secured_file (int fd)
163
#ifdef ENABLE_SELINUX_HACKS
165
struct secured_file_item *sf;
168
return 0; /* No file descriptor so it can't be secured either. */
170
/* Note that we print out a error here and claim that a file is
171
secure if something went wrong. */
172
if (fstat (fd, &buf))
174
log_error (_("fstat(%d) failed in %s: %s\n"), fd,
175
"is_secured_file", strerror (errno));
178
/* log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */
179
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
180
for (sf=secured_files; sf; sf = sf->next)
182
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
185
#endif /*ENABLE_SELINUX_HACKS*/
189
/* Return true if FNAME is corresponds to a secured file. Using NULL,
190
"" or "-" for FS is allowed and will return false. This function is
191
used before creating a file, thus it won't fail if the file does
194
is_secured_filename (const char *fname)
196
#ifdef ENABLE_SELINUX_HACKS
198
struct secured_file_item *sf;
200
if (iobuf_is_pipe_filename (fname) || !*fname)
203
/* Note that we print out a error here and claim that a file is
204
secure if something went wrong. */
205
if (stat (fname, &buf))
207
if (errno == ENOENT || errno == EPERM || errno == EACCES)
209
log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
210
"is_secured_filename", strerror (errno));
213
/* log_debug ("is_secured_filename (%s) i=%lu.%lu\n", fname, */
214
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
215
for (sf=secured_files; sf; sf = sf->next)
217
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
220
#endif /*ENABLE_SELINUX_HACKS*/
118
checksum_mpi( gcry_mpi_t a )
248
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 );
254
if ( gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a) )
256
/* Fixme: For numbers not in secure memory we should use a stack
257
* based buffer and only allocate a larger one if mpi_print returns
259
buffer = (gcry_is_secure(a)?
260
gcry_xmalloc_secure (nbytes) : gcry_xmalloc (nbytes));
261
if ( gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a) )
263
csum = checksum (buffer, nbytes);
155
static int did_note = 0;
159
log_info(_("Experimental algorithms should not be used!\n"));
164
280
print_pubkey_algo_note( int algo )
166
if( algo >= 100 && algo <= 110 )
282
if(algo >= 100 && algo <= 110)
288
log_info (_("WARNING: using experimental public key algorithm %s\n"),
289
gcry_pk_algo_name (algo));
294
log_info (_("WARNING: Elgamal sign+encrypt keys are deprecated\n"));
171
299
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"));
301
if(algo >= 100 && algo <= 110)
307
log_info (_("WARNING: using experimental cipher algorithm %s\n"),
308
openpgp_cipher_algo_name (algo));
196
314
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);
316
if(algo >= 100 && algo <= 110)
322
log_info (_("WARNING: using experimental digest algorithm %s\n"),
323
gcry_md_algo_name (algo));
326
else if(algo==DIGEST_ALGO_MD5)
327
log_info (_("WARNING: digest algorithm %s is deprecated\n"),
328
gcry_md_algo_name (algo));
332
/* Map OpenPGP algo numbers to those used by Libgcrypt. We need to do
333
this for algorithms we implemented in Libgcrypt after they become
336
map_cipher_openpgp_to_gcry (int algo)
340
case CIPHER_ALGO_CAMELLIA128: return 310;
341
case CIPHER_ALGO_CAMELLIA256: return 312;
342
default: return algo;
346
/* The inverse fucntion of above. */
348
map_cipher_gcry_to_openpgp (int algo)
352
case 310: return CIPHER_ALGO_CAMELLIA128;
353
case 312: return CIPHER_ALGO_CAMELLIA256;
354
default: return algo;
230
358
/****************
231
* Wrapper around the libgcrypt function with addional checks on
232
* openPGP contraints for the algo ID.
359
* Wrapper around the libgcrypt function with additonal checks on
360
* the OpenPGP contraints for the algo ID.
235
363
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?
365
/* (5 and 6 are marked reserved by rfc4880.) */
366
if ( algo < 0 || algo > 110 || algo == 5 || algo == 6 )
367
return gpg_error (GPG_ERR_CIPHER_ALGO);
369
/* Camellia is not yet defined for OpenPGP thus only allow it if
372
if (algo == CIPHER_ALGO_CAMELLIA128
373
|| algo == CIPHER_ALGO_CAMELLIA256)
374
return gpg_error (GPG_ERR_CIPHER_ALGO);
252
if (algo < 0 || algo > 110)
253
return GPG_ERR_PUBKEY_ALGO;
254
return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &value);
377
return gcry_cipher_test_algo (map_cipher_openpgp_to_gcry (algo));
380
/* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
381
string representation of the algorithm name. For unknown algorithm
382
IDs this function returns "?". */
384
openpgp_cipher_algo_name (int algo)
386
return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
392
openpgp_pk_test_algo( int algo )
394
/* Dont't allow type 20 keys unless in rfc2440 mode. */
395
if (!RFC2440 && algo == 20)
396
return gpg_error (GPG_ERR_PUBKEY_ALGO);
398
if (algo == GCRY_PK_ELG_E)
401
if (algo < 0 || algo > 110)
402
return gpg_error (GPG_ERR_PUBKEY_ALGO);
403
return gcry_pk_test_algo (algo);
407
openpgp_pk_test_algo2( int algo, unsigned int use )
409
size_t use_buf = use;
411
/* Dont't allow type 20 keys unless in rfc2440 mode. */
412
if (!RFC2440 && algo == 20)
413
return gpg_error (GPG_ERR_PUBKEY_ALGO);
415
if (algo == GCRY_PK_ELG_E)
418
if (algo < 0 || algo > 110)
419
return gpg_error (GPG_ERR_PUBKEY_ALGO);
421
return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &use_buf);
289
458
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;
460
/* Note: If the list of actual supported OpenPGP algorithms changes,
461
make sure that our hard coded values at
462
print_status_begin_signing() gets updated. */
463
/* 4, 5, 6, 7 are defined by rfc2440 but will be removed from the
464
next revision of the standard. */
465
if (algo < 0 || algo > 110 || (algo >= 4 && algo <= 7))
466
return gpg_error (GPG_ERR_DIGEST_ALGO);
467
return gcry_md_test_algo (algo);
589
721
log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
726
deprecated_command (const char *name)
728
log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
734
obsolete_option (const char *configname, unsigned int configlineno,
738
log_info (_("%s:%u: obsolete option \"%s\" - it has no effect\n"),
739
configname, configlineno, name);
741
log_info (_("WARNING: \"%s\" is an obsolete option - it has no effect\n"),
747
* Wrapper around gcry_cipher_map_name to provide a fallback using the
748
* "Sn" syntax as used by the preference strings.
751
string_to_cipher_algo (const char *string)
755
val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
756
if (!val && string && (string[0]=='S' || string[0]=='s'))
761
val = strtol (string, &endptr, 10);
762
if (!*string || *endptr || openpgp_cipher_test_algo (val))
770
* Wrapper around gcry_md_map_name to provide a fallback using the
771
* "Hn" syntax as used by the preference strings.
774
string_to_digest_algo (const char *string)
778
val = gcry_md_map_name (string);
779
if (!val && string && (string[0]=='H' || string[0]=='h'))
784
val = strtol (string, &endptr, 10);
785
if (!*string || *endptr || openpgp_md_test_algo (val))
593
795
compress_algo_to_string(int algo)
801
case COMPRESS_ALGO_NONE:
805
case COMPRESS_ALGO_ZIP:
809
case COMPRESS_ALGO_ZLIB:
814
case COMPRESS_ALGO_BZIP2:
669
895
compliance_option_string(void)
671
switch(opt.compliance)
689
compliance_string(void)
691
switch(opt.compliance)
899
switch(opt.compliance)
901
case CO_GNUPG: return "--gnupg";
902
case CO_RFC4880: return "--openpgp";
903
case CO_RFC2440: return "--rfc2440";
904
case CO_RFC1991: return "--rfc1991";
905
case CO_PGP2: return "--pgp2";
906
case CO_PGP6: return "--pgp6";
907
case CO_PGP7: return "--pgp7";
908
case CO_PGP8: return "--pgp8";
709
915
compliance_failure(void)
711
log_info(_("this message may not be usable by %s\n"),compliance_string());
919
switch(opt.compliance)
930
ver="OpenPGP (older)";
954
log_info(_("this message may not be usable by %s\n"),ver);
712
955
opt.compliance=CO_GNUPG;
958
/* Break a string into successive option pieces. Accepts single word
959
options and key=value argument options. */
961
optsep(char **stringp)
968
end=strpbrk(tok," ,=");
974
/* what we need to do now is scan along starting with *end,
975
If the next character we see (ignoring spaces) is an =
976
sign, then there is an argument. */
987
/* There is an argument, so grab that too. At this point,
988
ptr points to the first character of the argument. */
991
/* Is it a quoted argument? */
1000
end=strpbrk(ptr," ,");
1018
/* Breaks an option value into key and value. Returns NULL if there
1019
is no value. Note that "string" is modified to remove the =value
1022
argsplit(char *string)
1024
char *equals,*arg=NULL;
1026
equals=strchr(string,'=');
1035
quote=strchr(arg,'"');
1040
quote=strchr(arg,'"');
1048
/* Trim leading spaces off of the arg */
1049
spaces=strspn(arg," ");
1053
/* Trim tailing spaces off of the tag */
1054
space=strchr(string,' ');
1062
/* Return the length of the initial token, leaving off any
1065
optlen(const char *s)
1067
char *end=strpbrk(s," =");
716
parse_options(char *str,unsigned int *options,struct parse_options *opts)
1076
parse_options(char *str,unsigned int *options,
1077
struct parse_options *opts,int noisy)
720
while((tok=strsep(&str," ,")))
1081
if (str && !strcmp (str, "help"))
1085
/* Figure out the longest option name so we can line these up
1087
for(i=0;opts[i].name;i++)
1088
if(opts[i].help && maxlen<strlen(opts[i].name))
1089
maxlen=strlen(opts[i].name);
1091
for(i=0;opts[i].name;i++)
1093
printf("%s%*s%s\n",opts[i].name,
1094
maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
1099
while((tok=optsep(&str)))
724
1104
if(tok[0]=='\0')
733
1113
for(i=0;opts[i].name;i++)
735
if(ascii_strcasecmp(opts[i].name,tok)==0)
1115
size_t toklen=optlen(tok);
1117
if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
1119
/* We have a match, but it might be incomplete */
1120
if(toklen!=strlen(opts[i].name))
1124
for(j=i+1;opts[j].name;j++)
1126
if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
1129
log_info(_("ambiguous option `%s'\n"),otok);
738
*options&=~opts[i].bit;
1137
*options&=~opts[i].bit;
1139
*opts[i].value=NULL;
740
*options|=opts[i].bit;
1143
*options|=opts[i].bit;
1145
*opts[i].value=argsplit(tok);
745
1151
if(!opts[i].name)
1154
log_info(_("unknown option `%s'\n"),otok);
1163
/* Return a new malloced string by unescaping the string S. Escaping
1164
is percent escaping and '+'/space mapping. A binary nul will
1165
silently be replaced by a 0xFF. */
1167
unescape_percent_string (const unsigned char *s)
1171
buffer = d = xmalloc (strlen (s)+1);
1174
if (*s == '%' && s[1] && s[2])
1197
has_invalid_email_chars (const char *s)
1200
const char *valid_chars=
1201
"01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1209
else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
1211
else if ( at_seen && !strchr( valid_chars, *s ) )
1218
/* Check whether NAME represents a valid mailbox according to
1219
RFC822. Returns true if so. */
1221
is_valid_mailbox (const char *name)
1225
|| has_invalid_email_chars (name)
1226
|| string_count_chr (name,'@') != 1
1228
|| name[strlen(name)-1] == '@'
1229
|| name[strlen(name)-1] == '.'
1230
|| strstr (name, "..") );
1234
/* Similar to access(2), but uses PATH to find the file. */
1236
path_access(const char *file,int mode)
1241
envpath=getenv("PATH");
1244
#ifdef HAVE_DRIVE_LETTERS
1245
|| (((file[0]>='A' && file[0]<='Z')
1246
|| (file[0]>='a' && file[0]<='z'))
1252
return access(file,mode);
1255
/* At least as large as, but most often larger than we need. */
1256
char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
1257
char *split,*item,*path=xstrdup(envpath);
1261
while((item=strsep(&split,PATHSEP_S)))
1263
strcpy(buffer,item);
1265
strcat(buffer,file);
1266
ret=access(buffer,mode);
754
1280
/* Temporary helper. */
756
1282
pubkey_get_npkey( int algo )
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");
1368
/* FIXME: Use gcry_mpi_print directly. */
976
1370
mpi_print( FILE *fp, gcry_mpi_t a, int mode )