gpg: Use algorithm id 22 for EdDSA.
[gnupg.git] / common / miscellaneous.c
1 /* miscellaneous.c - Stuff not fitting elsewhere
2  *      Copyright (C) 2003, 2006 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * This file is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  *   - the GNU Lesser General Public License as published by the Free
10  *     Software Foundation; either version 3 of the License, or (at
11  *     your option) any later version.
12  *
13  * or
14  *
15  *   - the GNU General Public License as published by the Free
16  *     Software Foundation; either version 2 of the License, or (at
17  *     your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * This file is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 #include <config.h>
31 #include <stdlib.h>
32 #include <errno.h>
33
34 #define JNLIB_NEED_LOG_LOGV
35 #include "util.h"
36 #include "iobuf.h"
37 #include "i18n.h"
38
39 /* Used by libgcrypt for logging.  */
40 static void
41 my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
42 {
43   (void)dummy;
44
45   /* Map the log levels.  */
46   switch (level)
47     {
48     case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
49     case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
50     case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
51     case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
52     case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
53     case GCRY_LOG_BUG:  level = JNLIB_LOG_BUG; break;
54     case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
55     default:            level = JNLIB_LOG_ERROR; break;
56     }
57   log_logv (level, fmt, arg_ptr);
58 }
59
60
61 /* This function is called by libgcrypt on a fatal error.  */
62 static void
63 my_gcry_fatalerror_handler (void *opaque, int rc, const char *text)
64 {
65   (void)opaque;
66
67   log_fatal ("libgcrypt problem: %s\n", text ? text : gpg_strerror (rc));
68   abort ();
69 }
70
71
72 /* This function is called by libgcrypt if it ran out of core and
73    there is no way to return that error to the caller.  We do our own
74    function here to make use of our logging functions. */
75 static int
76 my_gcry_outofcore_handler (void *opaque, size_t req_n, unsigned int flags)
77 {
78   static int been_here;  /* Used to protect against recursive calls. */
79
80   (void)opaque;
81
82   if (!been_here)
83     {
84       been_here = 1;
85       if ( (flags & 1) )
86         log_fatal (_("out of core in secure memory "
87                      "while allocating %lu bytes"), (unsigned long)req_n);
88       else
89         log_fatal (_("out of core while allocating %lu bytes"),
90                    (unsigned long)req_n);
91     }
92   return 0; /* Let libgcrypt call its own fatal error handler.
93                Actually this will turn out to be
94                my_gcry_fatalerror_handler. */
95 }
96
97
98 /* Setup libgcrypt to use our own logging functions.  Should be used
99    early at startup. */
100 void
101 setup_libgcrypt_logging (void)
102 {
103   gcry_set_log_handler (my_gcry_logger, NULL);
104   gcry_set_fatalerror_handler (my_gcry_fatalerror_handler, NULL);
105   gcry_set_outofcore_handler (my_gcry_outofcore_handler, NULL);
106 }
107
108 /* A wrapper around gcry_cipher_algo_name to return the string
109    "AES-128" instead of "AES".  Given that we have an alias in
110    libgcrypt for it, it does not harm to too much to return this other
111    string.  Some users complained that we print "AES" but "AES192"
112    and "AES256".  We can't fix that in libgcrypt but it is pretty
113    safe to do it in an application. */
114 const char *
115 gnupg_cipher_algo_name (int algo)
116 {
117   const char *s;
118
119   s = gcry_cipher_algo_name (algo);
120   if (!strcmp (s, "AES"))
121     s = "AES128";
122   return s;
123 }
124
125
126 /* Decide whether the filename is stdout or a real filename and return
127  * an appropriate string.  */
128 const char *
129 print_fname_stdout (const char *s)
130 {
131     if( !s || (*s == '-' && !s[1]) )
132         return "[stdout]";
133     return s;
134 }
135
136
137 /* Decide whether the filename is stdin or a real filename and return
138  * an appropriate string.  */
139 const char *
140 print_fname_stdin (const char *s)
141 {
142     if( !s || (*s == '-' && !s[1]) )
143         return "[stdin]";
144     return s;
145 }
146
147
148 static int
149 do_print_utf8_buffer (estream_t stream,
150                       const void *buffer, size_t length,
151                       const char *delimiters, size_t *bytes_written)
152 {
153   const char *p = buffer;
154   size_t i;
155
156   /* We can handle plain ascii simpler, so check for it first. */
157   for (i=0; i < length; i++ )
158     {
159       if ( (p[i] & 0x80) )
160         break;
161     }
162   if (i < length)
163     {
164       int delim = delimiters? *delimiters : 0;
165       char *buf;
166       int ret;
167
168       /*(utf8 conversion already does the control character quoting). */
169       buf = utf8_to_native (p, length, delim);
170       if (bytes_written)
171         *bytes_written = strlen (buf);
172       ret = es_fputs (buf, stream);
173       xfree (buf);
174       return ret == EOF? ret : (int)i;
175     }
176   else
177     return es_write_sanitized (stream, p, length, delimiters, bytes_written);
178 }
179
180
181 void
182 print_utf8_buffer3 (estream_t stream, const void *p, size_t n,
183                     const char *delim)
184 {
185   do_print_utf8_buffer (stream, p, n, delim, NULL);
186 }
187
188
189 void
190 print_utf8_buffer2 (estream_t stream, const void *p, size_t n, int delim)
191 {
192   char tmp[2];
193
194   tmp[0] = delim;
195   tmp[1] = 0;
196   do_print_utf8_buffer (stream, p, n, tmp, NULL);
197 }
198
199
200 void
201 print_utf8_buffer (estream_t stream, const void *p, size_t n)
202 {
203   do_print_utf8_buffer (stream, p, n, NULL, NULL);
204 }
205
206 /* Write LENGTH bytes of BUFFER to FP as a hex encoded string.
207    RESERVED must be 0. */
208 void
209 print_hexstring (FILE *fp, const void *buffer, size_t length, int reserved)
210 {
211 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
212   const unsigned char *s;
213
214   (void)reserved;
215
216   for (s = buffer; length; s++, length--)
217     {
218       putc ( tohex ((*s>>4)&15), fp);
219       putc ( tohex (*s&15), fp);
220     }
221 #undef tohex
222 }
223
224 char *
225 make_printable_string (const void *p, size_t n, int delim )
226 {
227   return sanitize_buffer (p, n, delim);
228 }
229
230
231
232 /*
233  * Check if the file is compressed.
234  */
235 int
236 is_file_compressed (const char *s, int *ret_rc)
237 {
238     iobuf_t a;
239     byte buf[4];
240     int i, rc = 0;
241     int overflow;
242
243     struct magic_compress_s {
244         size_t len;
245         byte magic[4];
246     } magic[] = {
247         { 3, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
248         { 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
249         { 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
250     };
251
252     if ( iobuf_is_pipe_filename (s) || !ret_rc )
253         return 0; /* We can't check stdin or no file was given */
254
255     a = iobuf_open( s );
256     if ( a == NULL ) {
257         *ret_rc = gpg_error_from_syserror ();
258         return 0;
259     }
260
261     if ( iobuf_get_filelength( a, &overflow ) < 4 && !overflow) {
262         *ret_rc = 0;
263         goto leave;
264     }
265
266     if ( iobuf_read( a, buf, 4 ) == -1 ) {
267         *ret_rc = a->error;
268         goto leave;
269     }
270
271     for ( i = 0; i < DIM( magic ); i++ ) {
272         if ( !memcmp( buf, magic[i].magic, magic[i].len ) ) {
273             *ret_rc = 0;
274             rc = 1;
275             break;
276         }
277     }
278
279 leave:
280     iobuf_close( a );
281     return rc;
282 }
283
284
285 /* Try match against each substring of multistr, delimited by | */
286 int
287 match_multistr (const char *multistr,const char *match)
288 {
289   do
290     {
291       size_t seglen = strcspn (multistr,"|");
292       if (!seglen)
293         break;
294       /* Using the localized strncasecmp! */
295       if (strncasecmp(multistr,match,seglen)==0)
296         return 1;
297       multistr += seglen;
298       if (*multistr == '|')
299         multistr++;
300     }
301   while (*multistr);
302
303   return 0;
304 }
305
306
307 \f
308 /* Parse the first portion of the version number S and store it at
309    NUMBER.  On success, the function returns a pointer into S starting
310    with the first character, which is not part of the initial number
311    portion; on failure, NULL is returned.  */
312 static const char*
313 parse_version_number (const char *s, int *number)
314 {
315   int val = 0;
316
317   if (*s == '0' && digitp (s+1))
318     return NULL; /* Leading zeros are not allowed.  */
319   for (; digitp (s); s++ )
320     {
321       val *= 10;
322       val += *s - '0';
323     }
324   *number = val;
325   return val < 0? NULL : s;
326 }
327
328 /* Break up the complete string representation of the version number S,
329    which is expected to have this format:
330
331       <major number>.<minor number>.<micro number><patch level>.
332
333    The major, minor and micro number components will be stored at
334    MAJOR, MINOR and MICRO. On success, a pointer to the last
335    component, the patch level, will be returned; on failure, NULL will
336    be returned.  */
337 static const char *
338 parse_version_string (const char *s, int *major, int *minor, int *micro)
339 {
340   s = parse_version_number (s, major);
341   if (!s || *s != '.')
342     return NULL;
343   s++;
344   s = parse_version_number (s, minor);
345   if (!s || *s != '.')
346     return NULL;
347   s++;
348   s = parse_version_number (s, micro);
349   if (!s)
350     return NULL;
351   return s; /* Patchlevel.  */
352 }
353
354 /* Return true if version string is at least version B. */
355 int
356 gnupg_compare_version (const char *a, const char *b)
357 {
358   int a_major, a_minor, a_micro;
359   int b_major, b_minor, b_micro;
360   const char *a_plvl, *b_plvl;
361
362   if (!a || !b)
363     return 0;
364
365   /* Parse version A.  */
366   a_plvl = parse_version_string (a, &a_major, &a_minor, &a_micro);
367   if (!a_plvl )
368     return 0; /* Invalid version number.  */
369
370   /* Parse version B.  */
371   b_plvl = parse_version_string (b, &b_major, &b_minor, &b_micro);
372   if (!b_plvl )
373     return 0; /* Invalid version number.  */
374
375   /* Compare version numbers.  */
376   return (a_major > b_major
377           || (a_major == b_major && a_minor > b_minor)
378           || (a_major == b_major && a_minor == b_minor
379               && a_micro > b_micro)
380           || (a_major == b_major && a_minor == b_minor
381               && a_micro == b_micro
382               && strcmp (a_plvl, b_plvl) >= 0));
383 }