LCOV - code coverage report
Current view: top level - g10 - misc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 305 673 45.3 %
Date: 2016-09-12 13:01:59 Functions: 39 53 73.6 %

          Line data    Source code
       1             : /* misc.c - miscellaneous functions
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
       3             :  *               2008, 2009, 2010 Free Software Foundation, Inc.
       4             :  * Copyright (C) 2014 Werner Koch
       5             :  *
       6             :  * This file is part of GnuPG.
       7             :  *
       8             :  * GnuPG is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * GnuPG is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include <config.h>
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <unistd.h>
      27             : #include <errno.h>
      28             : #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
      29             : #include <asm/sysinfo.h>
      30             : #include <asm/unistd.h>
      31             : #endif
      32             : #ifdef HAVE_SETRLIMIT
      33             : #include <time.h>
      34             : #include <sys/time.h>
      35             : #include <sys/resource.h>
      36             : #endif
      37             : #ifdef ENABLE_SELINUX_HACKS
      38             : #include <sys/stat.h>
      39             : #endif
      40             : 
      41             : #ifdef HAVE_W32_SYSTEM
      42             : #include <time.h>
      43             : #include <process.h>
      44             : #ifdef HAVE_WINSOCK2_H
      45             : # include <winsock2.h>
      46             : #endif
      47             : #include <windows.h>
      48             : #include <shlobj.h>
      49             : #ifndef CSIDL_APPDATA
      50             : #define CSIDL_APPDATA 0x001a
      51             : #endif
      52             : #ifndef CSIDL_LOCAL_APPDATA
      53             : #define CSIDL_LOCAL_APPDATA 0x001c
      54             : #endif
      55             : #ifndef CSIDL_FLAG_CREATE
      56             : #define CSIDL_FLAG_CREATE 0x8000
      57             : #endif
      58             : #endif /*HAVE_W32_SYSTEM*/
      59             : 
      60             : #include "gpg.h"
      61             : #ifdef HAVE_W32_SYSTEM
      62             : # include "status.h"
      63             : #endif /*HAVE_W32_SYSTEM*/
      64             : #include "util.h"
      65             : #include "main.h"
      66             : #include "photoid.h"
      67             : #include "options.h"
      68             : #include "call-agent.h"
      69             : #include "i18n.h"
      70             : #include "zb32.h"
      71             : 
      72             : 
      73             : #ifdef ENABLE_SELINUX_HACKS
      74             : /* A object and a global variable to keep track of files marked as
      75             :    secured. */
      76             : struct secured_file_item
      77             : {
      78             :   struct secured_file_item *next;
      79             :   ino_t ino;
      80             :   dev_t dev;
      81             : };
      82             : static struct secured_file_item *secured_files;
      83             : #endif /*ENABLE_SELINUX_HACKS*/
      84             : 
      85             : 
      86             : 
      87             : 
      88             : /* For the sake of SELinux we want to restrict access through gpg to
      89             :    certain files we keep under our own control.  This function
      90             :    registers such a file and is_secured_file may then be used to
      91             :    check whether a file has ben registered as secured. */
      92             : void
      93        1775 : register_secured_file (const char *fname)
      94             : {
      95             : #ifdef ENABLE_SELINUX_HACKS
      96             :   struct stat buf;
      97             :   struct secured_file_item *sf;
      98             : 
      99             :   /* Note that we stop immediately if something goes wrong here. */
     100             :   if (stat (fname, &buf))
     101             :     log_fatal (_("fstat of '%s' failed in %s: %s\n"), fname,
     102             :                "register_secured_file", strerror (errno));
     103             : /*   log_debug ("registering '%s' i=%lu.%lu\n", fname, */
     104             : /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
     105             :   for (sf=secured_files; sf; sf = sf->next)
     106             :     {
     107             :       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
     108             :         return; /* Already registered.  */
     109             :     }
     110             : 
     111             :   sf = xmalloc (sizeof *sf);
     112             :   sf->ino = buf.st_ino;
     113             :   sf->dev = buf.st_dev;
     114             :   sf->next = secured_files;
     115             :   secured_files = sf;
     116             : #else /*!ENABLE_SELINUX_HACKS*/
     117             :   (void)fname;
     118             : #endif /*!ENABLE_SELINUX_HACKS*/
     119        1775 : }
     120             : 
     121             : /* Remove a file registered as secure. */
     122             : void
     123           0 : unregister_secured_file (const char *fname)
     124             : {
     125             : #ifdef ENABLE_SELINUX_HACKS
     126             :   struct stat buf;
     127             :   struct secured_file_item *sf, *sfprev;
     128             : 
     129             :   if (stat (fname, &buf))
     130             :     {
     131             :       log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
     132             :                  "unregister_secured_file", strerror (errno));
     133             :       return;
     134             :     }
     135             : /*   log_debug ("unregistering '%s' i=%lu.%lu\n", fname,  */
     136             : /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
     137             :   for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
     138             :     {
     139             :       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
     140             :         {
     141             :           if (sfprev)
     142             :             sfprev->next = sf->next;
     143             :           else
     144             :             secured_files = sf->next;
     145             :           xfree (sf);
     146             :           return;
     147             :         }
     148             :     }
     149             : #else /*!ENABLE_SELINUX_HACKS*/
     150             :   (void)fname;
     151             : #endif /*!ENABLE_SELINUX_HACKS*/
     152           0 : }
     153             : 
     154             : /* Return true if FD is corresponds to a secured file.  Using -1 for
     155             :    FS is allowed and will return false. */
     156             : int
     157        2955 : is_secured_file (int fd)
     158             : {
     159             : #ifdef ENABLE_SELINUX_HACKS
     160             :   struct stat buf;
     161             :   struct secured_file_item *sf;
     162             : 
     163             :   if (fd == -1)
     164             :     return 0; /* No file descriptor so it can't be secured either.  */
     165             : 
     166             :   /* Note that we print out a error here and claim that a file is
     167             :      secure if something went wrong. */
     168             :   if (fstat (fd, &buf))
     169             :     {
     170             :       log_error (_("fstat(%d) failed in %s: %s\n"), fd,
     171             :                  "is_secured_file", strerror (errno));
     172             :       return 1;
     173             :     }
     174             : /*   log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */
     175             : /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
     176             :   for (sf=secured_files; sf; sf = sf->next)
     177             :     {
     178             :       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
     179             :         return 1; /* Yes.  */
     180             :     }
     181             : #else /*!ENABLE_SELINUX_HACKS*/
     182             :   (void)fd;
     183             : #endif /*!ENABLE_SELINUX_HACKS*/
     184        2955 :   return 0; /* No. */
     185             : }
     186             : 
     187             : /* Return true if FNAME is corresponds to a secured file.  Using NULL,
     188             :    "" or "-" for FS is allowed and will return false. This function is
     189             :    used before creating a file, thus it won't fail if the file does
     190             :    not exist. */
     191             : int
     192        1097 : is_secured_filename (const char *fname)
     193             : {
     194             : #ifdef ENABLE_SELINUX_HACKS
     195             :   struct stat buf;
     196             :   struct secured_file_item *sf;
     197             : 
     198             :   if (iobuf_is_pipe_filename (fname) || !*fname)
     199             :     return 0;
     200             : 
     201             :   /* Note that we print out a error here and claim that a file is
     202             :      secure if something went wrong. */
     203             :   if (stat (fname, &buf))
     204             :     {
     205             :       if (errno == ENOENT || errno == EPERM || errno == EACCES)
     206             :         return 0;
     207             :       log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
     208             :                  "is_secured_filename", strerror (errno));
     209             :       return 1;
     210             :     }
     211             : /*   log_debug ("is_secured_filename (%s) i=%lu.%lu\n", fname, */
     212             : /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
     213             :   for (sf=secured_files; sf; sf = sf->next)
     214             :     {
     215             :       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
     216             :         return 1; /* Yes.  */
     217             :     }
     218             : #else /*!ENABLE_SELINUX_HACKS*/
     219             :   (void)fname;
     220             : #endif /*!ENABLE_SELINUX_HACKS*/
     221        1097 :   return 0; /* No. */
     222             : }
     223             : 
     224             : 
     225             : 
     226             : u16
     227           0 : checksum_u16( unsigned n )
     228             : {
     229             :     u16 a;
     230             : 
     231           0 :     a  = (n >> 8) & 0xff;
     232           0 :     a += n & 0xff;
     233           0 :     return a;
     234             : }
     235             : 
     236             : 
     237             : u16
     238           6 : checksum( byte *p, unsigned n )
     239             : {
     240             :     u16 a;
     241             : 
     242         388 :     for(a=0; n; n-- )
     243         382 :         a += *p++;
     244           6 :     return a;
     245             : }
     246             : 
     247             : u16
     248           6 : checksum_mpi (gcry_mpi_t a)
     249             : {
     250             :   u16 csum;
     251             :   byte *buffer;
     252             :   size_t nbytes;
     253             : 
     254           6 :   if ( gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a) )
     255           0 :     BUG ();
     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
     258             :    * an error. */
     259          12 :   buffer = (gcry_is_secure(a)?
     260           6 :             gcry_xmalloc_secure (nbytes) : gcry_xmalloc (nbytes));
     261           6 :   if ( gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a) )
     262           0 :     BUG ();
     263           6 :   csum = checksum (buffer, nbytes);
     264           6 :   xfree (buffer);
     265           6 :   return csum;
     266             : }
     267             : 
     268             : 
     269             : void
     270         391 : print_pubkey_algo_note (pubkey_algo_t algo)
     271             : {
     272         391 :   if(algo >= 100 && algo <= 110)
     273           0 :     {
     274             :       static int warn=0;
     275           0 :       if(!warn)
     276             :         {
     277           0 :           warn=1;
     278           0 :           es_fflush (es_stdout);
     279           0 :           log_info (_("WARNING: using experimental public key algorithm %s\n"),
     280             :                     openpgp_pk_algo_name (algo));
     281             :         }
     282             :     }
     283         391 :   else if (algo == PUBKEY_ALGO_ELGAMAL)
     284             :     {
     285           0 :       es_fflush (es_stdout);
     286           0 :       log_info (_("WARNING: Elgamal sign+encrypt keys are deprecated\n"));
     287             :     }
     288         391 : }
     289             : 
     290             : void
     291         467 : print_cipher_algo_note (cipher_algo_t algo)
     292             : {
     293         467 :   if(algo >= 100 && algo <= 110)
     294             :     {
     295             :       static int warn=0;
     296           0 :       if(!warn)
     297             :         {
     298           0 :           warn=1;
     299           0 :           es_fflush (es_stdout);
     300           0 :           log_info (_("WARNING: using experimental cipher algorithm %s\n"),
     301             :                     openpgp_cipher_algo_name (algo));
     302             :         }
     303             :     }
     304         467 : }
     305             : 
     306             : void
     307         136 : print_digest_algo_note (digest_algo_t algo)
     308             : {
     309         136 :   const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo);
     310             :   const struct weakhash *weak;
     311             : 
     312         136 :   if(algo >= 100 && algo <= 110)
     313           0 :     {
     314             :       static int warn=0;
     315           0 :       if(!warn)
     316             :         {
     317           0 :           warn=1;
     318           0 :           es_fflush (es_stdout);
     319           0 :           log_info (_("WARNING: using experimental digest algorithm %s\n"),
     320             :                     gcry_md_algo_name (galgo));
     321             :         }
     322             :     }
     323             :   else
     324         272 :       for (weak = opt.weak_digests; weak != NULL; weak = weak->next)
     325         136 :         if (weak->algo == galgo)
     326             :           {
     327           0 :             es_fflush (es_stdout);
     328           0 :             log_info (_("WARNING: digest algorithm %s is deprecated\n"),
     329             :                       gcry_md_algo_name (galgo));
     330             :           }
     331         136 : }
     332             : 
     333             : 
     334             : void
     335           0 : print_digest_rejected_note (enum gcry_md_algos algo)
     336             : {
     337             :   struct weakhash* weak;
     338           0 :   int show = 1;
     339           0 :   for (weak = opt.weak_digests; weak; weak = weak->next)
     340           0 :     if (weak->algo == algo)
     341             :       {
     342           0 :         if (weak->rejection_shown)
     343           0 :           show = 0;
     344             :         else
     345           0 :           weak->rejection_shown = 1;
     346           0 :         break;
     347             :       }
     348             : 
     349           0 :   if (show)
     350             :     {
     351           0 :       es_fflush (es_stdout);
     352           0 :       log_info
     353           0 :         (_("Note: signatures using the %s algorithm are rejected\n"),
     354             :          gcry_md_algo_name(algo));
     355             :     }
     356           0 : }
     357             : 
     358             : 
     359             : /* Print a message
     360             :  *  "(reported error: %s)\n
     361             :  * in verbose mode to further explain an error.  If the error code has
     362             :  * the value IGNORE_EC no message is printed.  A message is also not
     363             :  * printed if ERR is 0.  */
     364             : void
     365           0 : print_reported_error (gpg_error_t err, gpg_err_code_t ignore_ec)
     366             : {
     367           0 :   if (!opt.verbose)
     368           0 :     return;
     369             : 
     370           0 :   if (!gpg_err_code (err))
     371             :     ;
     372           0 :   else if (gpg_err_code (err) == ignore_ec)
     373             :     ;
     374           0 :   else if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
     375           0 :     log_info (_("(reported error: %s)\n"),
     376             :               gpg_strerror (err));
     377             :   else
     378           0 :     log_info (_("(reported error: %s <%s>)\n"),
     379             :               gpg_strerror (err), gpg_strsource (err));
     380             : 
     381             : }
     382             : 
     383             : 
     384             : /* Print a message
     385             :  *   "(further info: %s)\n
     386             :  * in verbose mode to further explain an error.  That message is
     387             :  * intended to help debug a problem and should not be translated.
     388             :  */
     389             : void
     390           0 : print_further_info (const char *format, ...)
     391             : {
     392             :   va_list arg_ptr;
     393             : 
     394           0 :   if (!opt.verbose)
     395           0 :     return;
     396             : 
     397           0 :   log_info (_("(further info: "));
     398           0 :   va_start (arg_ptr, format);
     399           0 :   log_logv (GPGRT_LOG_CONT, format, arg_ptr);
     400           0 :   va_end (arg_ptr);
     401           0 :   log_printf (")\n");
     402             : }
     403             : 
     404             : 
     405             : /* Map OpenPGP algo numbers to those used by Libgcrypt.  We need to do
     406             :    this for algorithms we implemented in Libgcrypt after they become
     407             :    part of OpenPGP.  */
     408             : enum gcry_cipher_algos
     409      108962 : map_cipher_openpgp_to_gcry (cipher_algo_t algo)
     410             : {
     411      108962 :   switch (algo)
     412             :     {
     413         125 :     case CIPHER_ALGO_NONE:        return GCRY_CIPHER_NONE;
     414             : 
     415             : #ifdef GPG_USE_IDEA
     416        1048 :     case CIPHER_ALGO_IDEA:        return GCRY_CIPHER_IDEA;
     417             : #else
     418             :     case CIPHER_ALGO_IDEA:        return 0;
     419             : #endif
     420             : 
     421         623 :     case CIPHER_ALGO_3DES:        return GCRY_CIPHER_3DES;
     422             : 
     423             : #ifdef GPG_USE_CAST5
     424        1277 :     case CIPHER_ALGO_CAST5:       return GCRY_CIPHER_CAST5;
     425             : #else
     426             :     case CIPHER_ALGO_CAST5:       return 0;
     427             : #endif
     428             : 
     429             : #ifdef GPG_USE_BLOWFISH
     430         454 :     case CIPHER_ALGO_BLOWFISH:    return GCRY_CIPHER_BLOWFISH;
     431             : #else
     432             :     case CIPHER_ALGO_BLOWFISH:    return 0;
     433             : #endif
     434             : 
     435             : #ifdef GPG_USE_AES128
     436         679 :     case CIPHER_ALGO_AES:         return GCRY_CIPHER_AES;
     437             : #else
     438             :     case CIPHER_ALGO_AES:         return 0;
     439             : #endif
     440             : 
     441             : #ifdef GPG_USE_AES192
     442         580 :     case CIPHER_ALGO_AES192:      return GCRY_CIPHER_AES192;
     443             : #else
     444             :     case CIPHER_ALGO_AES192:      return 0;
     445             : #endif
     446             : 
     447             : #ifdef GPG_USE_AES256
     448       90010 :     case CIPHER_ALGO_AES256:      return GCRY_CIPHER_AES256;
     449             : #else
     450             :     case CIPHER_ALGO_AES256:      return 0;
     451             : #endif
     452             : 
     453             : #ifdef GPG_USE_TWOFISH
     454         456 :     case CIPHER_ALGO_TWOFISH:     return GCRY_CIPHER_TWOFISH;
     455             : #else
     456             :     case CIPHER_ALGO_TWOFISH:     return 0;
     457             : #endif
     458             : 
     459             : #ifdef GPG_USE_CAMELLIA128
     460         445 :     case CIPHER_ALGO_CAMELLIA128: return GCRY_CIPHER_CAMELLIA128;
     461             : #else
     462             :     case CIPHER_ALGO_CAMELLIA128: return 0;
     463             : #endif
     464             : 
     465             : #ifdef GPG_USE_CAMELLIA192
     466         445 :     case CIPHER_ALGO_CAMELLIA192: return GCRY_CIPHER_CAMELLIA192;
     467             : #else
     468             :     case CIPHER_ALGO_CAMELLIA192: return 0;
     469             : #endif
     470             : 
     471             : #ifdef GPG_USE_CAMELLIA256
     472         445 :     case CIPHER_ALGO_CAMELLIA256: return GCRY_CIPHER_CAMELLIA256;
     473             : #else
     474             :     case CIPHER_ALGO_CAMELLIA256: return 0;
     475             : #endif
     476             :     }
     477       12375 :   return 0;
     478             : }
     479             : 
     480             : /* The inverse function of above.  */
     481             : static cipher_algo_t
     482         388 : map_cipher_gcry_to_openpgp (enum gcry_cipher_algos algo)
     483             : {
     484         388 :   switch (algo)
     485             :     {
     486          24 :     case GCRY_CIPHER_NONE:        return CIPHER_ALGO_NONE;
     487          34 :     case GCRY_CIPHER_IDEA:        return CIPHER_ALGO_IDEA;
     488          33 :     case GCRY_CIPHER_3DES:        return CIPHER_ALGO_3DES;
     489          33 :     case GCRY_CIPHER_CAST5:       return CIPHER_ALGO_CAST5;
     490          33 :     case GCRY_CIPHER_BLOWFISH:    return CIPHER_ALGO_BLOWFISH;
     491          33 :     case GCRY_CIPHER_AES:         return CIPHER_ALGO_AES;
     492          33 :     case GCRY_CIPHER_AES192:      return CIPHER_ALGO_AES192;
     493          33 :     case GCRY_CIPHER_AES256:      return CIPHER_ALGO_AES256;
     494          33 :     case GCRY_CIPHER_TWOFISH:     return CIPHER_ALGO_TWOFISH;
     495          33 :     case GCRY_CIPHER_CAMELLIA128: return CIPHER_ALGO_CAMELLIA128;
     496          33 :     case GCRY_CIPHER_CAMELLIA192: return CIPHER_ALGO_CAMELLIA192;
     497          33 :     case GCRY_CIPHER_CAMELLIA256: return CIPHER_ALGO_CAMELLIA256;
     498           0 :     default: return 0;
     499             :     }
     500             : }
     501             : 
     502             : /* Map Gcrypt public key algorithm numbers to those used by OpenPGP.
     503             :    FIXME: This mapping is used at only two places - we should get rid
     504             :    of it.  */
     505             : pubkey_algo_t
     506           6 : map_pk_gcry_to_openpgp (enum gcry_pk_algos algo)
     507             : {
     508           6 :   switch (algo)
     509             :     {
     510           0 :     case GCRY_PK_ECDSA:  return PUBKEY_ALGO_ECDSA;
     511           0 :     case GCRY_PK_ECDH:   return PUBKEY_ALGO_ECDH;
     512           6 :     default: return algo < 110 ? algo : 0;
     513             :     }
     514             : }
     515             : 
     516             : 
     517             : /* Return the block length of an OpenPGP cipher algorithm.  */
     518             : int
     519          31 : openpgp_cipher_blocklen (cipher_algo_t algo)
     520             : {
     521             :   /* We use the numbers from OpenPGP to be sure that we get the right
     522             :      block length.  This is so that the packet parsing code works even
     523             :      for unknown algorithms (for which we assume 8 due to tradition).
     524             : 
     525             :      NOTE: If you change the the returned blocklen above 16, check
     526             :      the callers because they may use a fixed size buffer of that
     527             :      size. */
     528          31 :   switch (algo)
     529             :     {
     530             :     case CIPHER_ALGO_AES:
     531             :     case CIPHER_ALGO_AES192:
     532             :     case CIPHER_ALGO_AES256:
     533             :     case CIPHER_ALGO_TWOFISH:
     534             :     case CIPHER_ALGO_CAMELLIA128:
     535             :     case CIPHER_ALGO_CAMELLIA192:
     536             :     case CIPHER_ALGO_CAMELLIA256:
     537          25 :       return 16;
     538             : 
     539             :     default:
     540           6 :       return 8;
     541             :     }
     542             : }
     543             : 
     544             : /****************
     545             :  * Wrapper around the libgcrypt function with additional checks on
     546             :  * the OpenPGP contraints for the algo ID.
     547             :  */
     548             : int
     549       16926 : openpgp_cipher_test_algo (cipher_algo_t algo)
     550             : {
     551             :   enum gcry_cipher_algos ga;
     552             : 
     553       16926 :   ga = map_cipher_openpgp_to_gcry (algo);
     554       16926 :   if (!ga)
     555       12500 :     return gpg_error (GPG_ERR_CIPHER_ALGO);
     556             : 
     557        4426 :   return gcry_cipher_test_algo (ga);
     558             : }
     559             : 
     560             : /* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
     561             :    string representation of the algorithm name.  For unknown algorithm
     562             :    IDs this function returns "?".  */
     563             : const char *
     564        1821 : openpgp_cipher_algo_name (cipher_algo_t algo)
     565             : {
     566        1821 :   switch (algo)
     567             :     {
     568           0 :     case CIPHER_ALGO_NONE:        break;
     569         146 :     case CIPHER_ALGO_IDEA:        return "IDEA";
     570         146 :     case CIPHER_ALGO_3DES:        return "3DES";
     571         148 :     case CIPHER_ALGO_CAST5:       return "CAST5";
     572         172 :     case CIPHER_ALGO_BLOWFISH:    return "BLOWFISH";
     573         195 :     case CIPHER_ALGO_AES:         return "AES";
     574         158 :     case CIPHER_ALGO_AES192:      return "AES192";
     575         168 :     case CIPHER_ALGO_AES256:      return "AES256";
     576         172 :     case CIPHER_ALGO_TWOFISH:     return "TWOFISH";
     577         172 :     case CIPHER_ALGO_CAMELLIA128: return "CAMELLIA128";
     578         172 :     case CIPHER_ALGO_CAMELLIA192: return "CAMELLIA192";
     579         172 :     case CIPHER_ALGO_CAMELLIA256: return "CAMELLIA256";
     580             :     }
     581           0 :   return "?";
     582             : }
     583             : 
     584             : 
     585             : /* Return 0 if ALGO is a supported OpenPGP public key algorithm.  */
     586             : int
     587       17039 : openpgp_pk_test_algo (pubkey_algo_t algo)
     588             : {
     589       17039 :   return openpgp_pk_test_algo2 (algo, 0);
     590             : }
     591             : 
     592             : 
     593             : /* Return 0 if ALGO is a supported OpenPGP public key algorithm and
     594             :    allows the usage USE.  */
     595             : int
     596       17681 : openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
     597             : {
     598       17681 :   enum gcry_pk_algos ga = 0;
     599       17681 :   size_t use_buf = use;
     600             : 
     601       17681 :   switch (algo)
     602             :     {
     603             : #ifdef GPG_USE_RSA
     604         737 :     case PUBKEY_ALGO_RSA:       ga = GCRY_PK_RSA;   break;
     605           0 :     case PUBKEY_ALGO_RSA_E:     ga = GCRY_PK_RSA_E; break;
     606           0 :     case PUBKEY_ALGO_RSA_S:     ga = GCRY_PK_RSA_S; break;
     607             : #else
     608             :     case PUBKEY_ALGO_RSA:       break;
     609             :     case PUBKEY_ALGO_RSA_E:     break;
     610             :     case PUBKEY_ALGO_RSA_S:     break;
     611             : #endif
     612             : 
     613        2323 :     case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG;   break;
     614        1007 :     case PUBKEY_ALGO_DSA:       ga = GCRY_PK_DSA;   break;
     615             : 
     616             : #ifdef GPG_USE_ECDH
     617         385 :     case PUBKEY_ALGO_ECDH:      ga = GCRY_PK_ECC;   break;
     618             : #else
     619             :     case PUBKEY_ALGO_ECDH:      break;
     620             : #endif
     621             : 
     622             : #ifdef GPG_USE_ECDSA
     623         203 :     case PUBKEY_ALGO_ECDSA:     ga = GCRY_PK_ECC;   break;
     624             : #else
     625             :     case PUBKEY_ALGO_ECDSA:     break;
     626             : #endif
     627             : 
     628             : #ifdef GPG_USE_EDDSA
     629         151 :     case PUBKEY_ALGO_EDDSA:     ga = GCRY_PK_ECC;   break;
     630             : #else
     631             :     case PUBKEY_ALGO_EDDSA:     break;
     632             : #endif
     633             : 
     634             :     case PUBKEY_ALGO_ELGAMAL:
     635             :       /* Dont't allow type 20 keys unless in rfc2440 mode.  */
     636         125 :       if (RFC2440)
     637           0 :         ga = GCRY_PK_ELG;
     638         125 :       break;
     639             :     }
     640       17681 :   if (!ga)
     641       12875 :     return gpg_error (GPG_ERR_PUBKEY_ALGO);
     642             : 
     643             :   /* No check whether Libgcrypt has support for the algorithm.  */
     644        4806 :   return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
     645             : }
     646             : 
     647             : 
     648             : int
     649        4526 : openpgp_pk_algo_usage ( int algo )
     650             : {
     651        4526 :     int use = 0;
     652             : 
     653             :     /* They are hardwired in gpg 1.0. */
     654        4526 :     switch ( algo ) {
     655             :       case PUBKEY_ALGO_RSA:
     656         610 :           use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
     657             :                  | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
     658         610 :           break;
     659             :       case PUBKEY_ALGO_RSA_E:
     660             :       case PUBKEY_ALGO_ECDH:
     661         212 :           use = PUBKEY_USAGE_ENC;
     662         212 :           break;
     663             :       case PUBKEY_ALGO_RSA_S:
     664           0 :           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
     665           0 :           break;
     666             :       case PUBKEY_ALGO_ELGAMAL:
     667           0 :           if (RFC2440)
     668           0 :              use = PUBKEY_USAGE_ENC;
     669           0 :           break;
     670             :       case PUBKEY_ALGO_ELGAMAL_E:
     671        1743 :           use = PUBKEY_USAGE_ENC;
     672        1743 :           break;
     673             :       case PUBKEY_ALGO_DSA:
     674        1743 :           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
     675        1743 :           break;
     676             :       case PUBKEY_ALGO_ECDSA:
     677             :       case PUBKEY_ALGO_EDDSA:
     678         218 :           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
     679             :       default:
     680         218 :           break;
     681             :     }
     682        4526 :     return use;
     683             : }
     684             : 
     685             : /* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a
     686             :    string representation of the algorithm name.  For unknown algorithm
     687             :    IDs this function returns "?".  */
     688             : const char *
     689        1650 : openpgp_pk_algo_name (pubkey_algo_t algo)
     690             : {
     691        1650 :   switch (algo)
     692             :     {
     693             :     case PUBKEY_ALGO_RSA:
     694             :     case PUBKEY_ALGO_RSA_E:
     695         192 :     case PUBKEY_ALGO_RSA_S:     return "RSA";
     696             :     case PUBKEY_ALGO_ELGAMAL:
     697         605 :     case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
     698         350 :     case PUBKEY_ALGO_DSA:       return "DSA";
     699         191 :     case PUBKEY_ALGO_ECDH:      return "ECDH";
     700         185 :     case PUBKEY_ALGO_ECDSA:     return "ECDSA";
     701         127 :     case PUBKEY_ALGO_EDDSA:     return "EDDSA";
     702             :     }
     703           0 :   return "?";
     704             : }
     705             : 
     706             : 
     707             : /* Explicit mapping of OpenPGP digest algos to Libgcrypt.  */
     708             : /* FIXME: We do not yes use it everywhere.  */
     709             : enum gcry_md_algos
     710       29818 : map_md_openpgp_to_gcry (digest_algo_t algo)
     711             : {
     712       29818 :   switch (algo)
     713             :     {
     714             : #ifdef GPG_USE_MD5
     715         143 :     case DIGEST_ALGO_MD5:    return GCRY_MD_MD5;
     716             : #else
     717             :     case DIGEST_ALGO_MD5:    return 0;
     718             : #endif
     719             : 
     720        1374 :     case DIGEST_ALGO_SHA1:   return GCRY_MD_SHA1;
     721             : 
     722             : #ifdef GPG_USE_RMD160
     723         294 :     case DIGEST_ALGO_RMD160: return GCRY_MD_RMD160;
     724             : #else
     725             :     case DIGEST_ALGO_RMD160: return 0;
     726             : #endif
     727             : 
     728             : #ifdef GPG_USE_SHA224
     729         277 :     case DIGEST_ALGO_SHA224: return GCRY_MD_SHA224;
     730             : #else
     731             :     case DIGEST_ALGO_SHA224: return 0;
     732             : #endif
     733             : 
     734         599 :     case DIGEST_ALGO_SHA256: return GCRY_MD_SHA256;
     735             : 
     736             : #ifdef GPG_USE_SHA384
     737         317 :     case DIGEST_ALGO_SHA384: return GCRY_MD_SHA384;
     738             : #else
     739             :     case DIGEST_ALGO_SHA384: return 0;
     740             : #endif
     741             : 
     742             : #ifdef GPG_USE_SHA512
     743         321 :     case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
     744             : #else
     745             :     case DIGEST_ALGO_SHA512: return 0;
     746             : #endif
     747             :     }
     748       26493 :   return 0;
     749             : }
     750             : 
     751             : 
     752             : /* Return 0 if ALGO is suitable and implemented OpenPGP hash
     753             :    algorithm.  */
     754             : int
     755       15112 : openpgp_md_test_algo (digest_algo_t algo)
     756             : {
     757             :   enum gcry_md_algos ga;
     758             : 
     759       15112 :   ga = map_md_openpgp_to_gcry (algo);
     760       15112 :   if (!ga)
     761       13000 :     return gpg_error (GPG_ERR_DIGEST_ALGO);
     762             : 
     763        2112 :   return gcry_md_test_algo (ga);
     764             : }
     765             : 
     766             : 
     767             : /* Map the OpenPGP digest algorithm whose ID is contained in ALGO to a
     768             :    string representation of the algorithm name.  For unknown algorithm
     769             :    IDs this function returns "?".  */
     770             : const char *
     771         779 : openpgp_md_algo_name (int algo)
     772             : {
     773         779 :   switch (algo)
     774             :     {
     775           0 :     case DIGEST_ALGO_MD5:    return "MD5";
     776         154 :     case DIGEST_ALGO_SHA1:   return "SHA1";
     777         125 :     case DIGEST_ALGO_RMD160: return "RIPEMD160";
     778         125 :     case DIGEST_ALGO_SHA256: return "SHA256";
     779         125 :     case DIGEST_ALGO_SHA384: return "SHA384";
     780         125 :     case DIGEST_ALGO_SHA512: return "SHA512";
     781         125 :     case DIGEST_ALGO_SHA224: return "SHA224";
     782             :     }
     783           0 :   return "?";
     784             : }
     785             : 
     786             : 
     787             : static unsigned long
     788           0 : get_signature_count (PKT_public_key *pk)
     789             : {
     790             : #ifdef ENABLE_CARD_SUPPORT
     791             :   struct agent_card_info_s info;
     792             : 
     793             :   (void)pk;
     794           0 :   if (!agent_scd_getattr ("SIG-COUNTER",&info))
     795           0 :     return info.sig_counter;
     796             :   else
     797           0 :     return 0;
     798             : #else
     799             :   (void)pk;
     800             :   return 0;
     801             : #endif
     802             : }
     803             : 
     804             : /* Expand %-strings.  Returns a string which must be xfreed.  Returns
     805             :    NULL if the string cannot be expanded (too large). */
     806             : char *
     807           0 : pct_expando(const char *string,struct expando_args *args)
     808             : {
     809           0 :   const char *ch=string;
     810           0 :   int idx=0,maxlen=0,done=0;
     811           0 :   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
     812           0 :   char *ret=NULL;
     813             : 
     814           0 :   if(args->pk)
     815           0 :     keyid_from_pk(args->pk,pk_keyid);
     816             : 
     817           0 :   if(args->pksk)
     818           0 :     keyid_from_pk (args->pksk, sk_keyid);
     819             : 
     820             :   /* This is used so that %k works in photoid command strings in
     821             :      --list-secret-keys (which of course has a sk, but no pk). */
     822           0 :   if(!args->pk && args->pksk)
     823           0 :     keyid_from_pk (args->pksk, pk_keyid);
     824             : 
     825           0 :   while(*ch!='\0')
     826             :     {
     827           0 :       if(!done)
     828             :         {
     829             :           /* 8192 is way bigger than we'll need here */
     830           0 :           if(maxlen>=8192)
     831           0 :             goto fail;
     832             : 
     833           0 :           maxlen+=1024;
     834           0 :           ret=xrealloc(ret,maxlen);
     835             :         }
     836             : 
     837           0 :       done=0;
     838             : 
     839           0 :       if(*ch=='%')
     840             :         {
     841           0 :           switch(*(ch+1))
     842             :             {
     843             :             case 's': /* short key id */
     844           0 :               if(idx+8<maxlen)
     845             :                 {
     846           0 :                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
     847           0 :                   idx+=8;
     848           0 :                   done=1;
     849             :                 }
     850           0 :               break;
     851             : 
     852             :             case 'S': /* long key id */
     853           0 :               if(idx+16<maxlen)
     854             :                 {
     855           0 :                   sprintf(&ret[idx],"%08lX%08lX",
     856           0 :                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
     857           0 :                   idx+=16;
     858           0 :                   done=1;
     859             :                 }
     860           0 :               break;
     861             : 
     862             :             case 'k': /* short key id */
     863           0 :               if(idx+8<maxlen)
     864             :                 {
     865           0 :                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
     866           0 :                   idx+=8;
     867           0 :                   done=1;
     868             :                 }
     869           0 :               break;
     870             : 
     871             :             case 'K': /* long key id */
     872           0 :               if(idx+16<maxlen)
     873             :                 {
     874           0 :                   sprintf(&ret[idx],"%08lX%08lX",
     875           0 :                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
     876           0 :                   idx+=16;
     877           0 :                   done=1;
     878             :                 }
     879           0 :               break;
     880             : 
     881             :             case 'U': /* z-base-32 encoded user id hash. */
     882           0 :               if (args->namehash)
     883             :                 {
     884           0 :                   char *tmp = zb32_encode (args->namehash, 8*20);
     885           0 :                   if (tmp)
     886             :                     {
     887           0 :                       if (idx + strlen (tmp) < maxlen)
     888             :                         {
     889           0 :                           strcpy (ret+idx, tmp);
     890           0 :                           idx += strlen (tmp);
     891             :                         }
     892           0 :                       xfree (tmp);
     893           0 :                       done = 1;
     894             :                     }
     895             :                 }
     896           0 :               break;
     897             : 
     898             :             case 'c': /* signature count from card, if any. */
     899           0 :               if(idx+10<maxlen)
     900             :                 {
     901           0 :                   sprintf (&ret[idx],"%lu", get_signature_count (args->pksk));
     902           0 :                   idx+=strlen(&ret[idx]);
     903           0 :                   done=1;
     904             :                 }
     905           0 :               break;
     906             : 
     907             :             case 'f': /* Fingerprint of key being signed */
     908             :             case 'p': /* Fingerprint of the primary key making the signature. */
     909             :             case 'g': /* Fingerprint of the key making the signature.  */
     910             :               {
     911             :                 byte array[MAX_FINGERPRINT_LEN];
     912             :                 size_t len;
     913             :                 int i;
     914             : 
     915           0 :                 if ((*(ch+1))=='f' && args->pk)
     916           0 :                   fingerprint_from_pk (args->pk, array, &len);
     917           0 :                 else if ((*(ch+1))=='p' && args->pksk)
     918             :                   {
     919           0 :                     if(args->pksk->flags.primary)
     920           0 :                       fingerprint_from_pk (args->pksk, array, &len);
     921           0 :                     else if (args->pksk->main_keyid[0]
     922           0 :                              || args->pksk->main_keyid[1])
     923           0 :                       {
     924             :                         /* Not the primary key: Find the fingerprint
     925             :                            of the primary key.  */
     926           0 :                         PKT_public_key *pk=
     927             :                           xmalloc_clear(sizeof(PKT_public_key));
     928             : 
     929           0 :                         if (!get_pubkey_fast (pk,args->pksk->main_keyid))
     930           0 :                           fingerprint_from_pk (pk, array, &len);
     931             :                         else
     932           0 :                           memset (array, 0, (len=MAX_FINGERPRINT_LEN));
     933           0 :                         free_public_key (pk);
     934             :                       }
     935             :                     else /* Oops: info about the primary key missing.  */
     936           0 :                       memset(array,0,(len=MAX_FINGERPRINT_LEN));
     937             :                   }
     938           0 :                 else if((*(ch+1))=='g' && args->pksk)
     939           0 :                   fingerprint_from_pk (args->pksk, array, &len);
     940             :                 else
     941           0 :                   memset(array,0,(len=MAX_FINGERPRINT_LEN));
     942             : 
     943           0 :                 if(idx+(len*2)<maxlen)
     944             :                   {
     945           0 :                     for(i=0;i<len;i++)
     946             :                       {
     947           0 :                         sprintf(&ret[idx],"%02X",array[i]);
     948           0 :                         idx+=2;
     949             :                       }
     950           0 :                     done=1;
     951             :                   }
     952             :               }
     953           0 :               break;
     954             : 
     955             :             case 'v': /* validity letters */
     956           0 :               if(args->validity_info && idx+1<maxlen)
     957             :                 {
     958           0 :                   ret[idx++]=args->validity_info;
     959           0 :                   ret[idx]='\0';
     960           0 :                   done=1;
     961             :                 }
     962           0 :               break;
     963             : 
     964             :               /* The text string types */
     965             :             case 't':
     966             :             case 'T':
     967             :             case 'V':
     968             :               {
     969           0 :                 const char *str=NULL;
     970             : 
     971           0 :                 switch(*(ch+1))
     972             :                   {
     973             :                   case 't': /* e.g. "jpg" */
     974           0 :                     str=image_type_to_string(args->imagetype,0);
     975           0 :                     break;
     976             : 
     977             :                   case 'T': /* e.g. "image/jpeg" */
     978           0 :                     str=image_type_to_string(args->imagetype,2);
     979           0 :                     break;
     980             : 
     981             :                   case 'V': /* e.g. "full", "expired", etc. */
     982           0 :                     str=args->validity_string;
     983           0 :                     break;
     984             :                   }
     985             : 
     986           0 :                 if(str && idx+strlen(str)<maxlen)
     987             :                   {
     988           0 :                     strcpy(&ret[idx],str);
     989           0 :                     idx+=strlen(str);
     990           0 :                     done=1;
     991             :                   }
     992             :               }
     993           0 :               break;
     994             : 
     995             :             case '%':
     996           0 :               if(idx+1<maxlen)
     997             :                 {
     998           0 :                   ret[idx++]='%';
     999           0 :                   ret[idx]='\0';
    1000           0 :                   done=1;
    1001             :                 }
    1002           0 :               break;
    1003             : 
    1004             :               /* Any unknown %-keys (like %i, %o, %I, and %O) are
    1005             :                  passed through for later expansion.  Note this also
    1006             :                  handles the case where the last character in the
    1007             :                  string is a '%' - the terminating \0 will end up here
    1008             :                  and properly terminate the string. */
    1009             :             default:
    1010           0 :               if(idx+2<maxlen)
    1011             :                 {
    1012           0 :                   ret[idx++]='%';
    1013           0 :                   ret[idx++]=*(ch+1);
    1014           0 :                   ret[idx]='\0';
    1015           0 :                   done=1;
    1016             :                 }
    1017           0 :               break;
    1018             :               }
    1019             : 
    1020           0 :           if(done)
    1021           0 :             ch++;
    1022             :         }
    1023             :       else
    1024             :         {
    1025           0 :           if(idx+1<maxlen)
    1026             :             {
    1027           0 :               ret[idx++]=*ch;
    1028           0 :               ret[idx]='\0';
    1029           0 :               done=1;
    1030             :             }
    1031             :         }
    1032             : 
    1033           0 :       if(done)
    1034           0 :         ch++;
    1035             :     }
    1036             : 
    1037           0 :   return ret;
    1038             : 
    1039             :  fail:
    1040           0 :   xfree(ret);
    1041           0 :   return NULL;
    1042             : }
    1043             : 
    1044             : void
    1045           0 : deprecated_warning(const char *configname,unsigned int configlineno,
    1046             :                    const char *option,const char *repl1,const char *repl2)
    1047             : {
    1048           0 :   if(configname)
    1049             :     {
    1050           0 :       if(strncmp("--",option,2)==0)
    1051           0 :         option+=2;
    1052             : 
    1053           0 :       if(strncmp("--",repl1,2)==0)
    1054           0 :         repl1+=2;
    1055             : 
    1056           0 :       log_info(_("%s:%d: deprecated option \"%s\"\n"),
    1057             :                configname,configlineno,option);
    1058             :     }
    1059             :   else
    1060           0 :     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
    1061             : 
    1062           0 :   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
    1063           0 : }
    1064             : 
    1065             : 
    1066             : void
    1067           0 : deprecated_command (const char *name)
    1068             : {
    1069           0 :   log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
    1070             :            name);
    1071           0 : }
    1072             : 
    1073             : 
    1074             : void
    1075           0 : obsolete_scdaemon_option (const char *configname, unsigned int configlineno,
    1076             :                           const char *name)
    1077             : {
    1078           0 :   if (configname)
    1079           0 :     log_info (_("%s:%u: \"%s\" is obsolete in this file"
    1080             :                 " - it only has effect in %s\n"),
    1081             :               configname, configlineno, name, SCDAEMON_NAME EXTSEP_S "conf");
    1082             :   else
    1083           0 :     log_info (_("WARNING: \"%s%s\" is an obsolete option"
    1084             :                 " - it has no effect except on %s\n"),
    1085             :               "--", name, SCDAEMON_NAME);
    1086           0 : }
    1087             : 
    1088             : 
    1089             : /*
    1090             :  * Wrapper around gcry_cipher_map_name to provide a fallback using the
    1091             :  * "Sn" syntax as used by the preference strings.
    1092             :  */
    1093             : int
    1094         388 : string_to_cipher_algo (const char *string)
    1095             : {
    1096             :   int val;
    1097             : 
    1098         388 :   val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
    1099         388 :   if (!val && string && (string[0]=='S' || string[0]=='s'))
    1100             :     {
    1101             :       char *endptr;
    1102             : 
    1103           8 :       string++;
    1104           8 :       val = strtol (string, &endptr, 10);
    1105           8 :       if (!*string || *endptr || openpgp_cipher_test_algo (val))
    1106           0 :         val = 0;
    1107             :     }
    1108             : 
    1109         388 :   return val;
    1110             : }
    1111             : 
    1112             : /*
    1113             :  * Wrapper around gcry_md_map_name to provide a fallback using the
    1114             :  * "Hn" syntax as used by the preference strings.
    1115             :  */
    1116             : int
    1117        1860 : string_to_digest_algo (const char *string)
    1118             : {
    1119             :   int val;
    1120             : 
    1121             :   /* FIXME: We should make use of our wrapper function and not assume
    1122             :      that there is a 1 to 1 mapping between OpenPGP and Libgcrypt.  */
    1123        1860 :   val = gcry_md_map_name (string);
    1124        1860 :   if (!val && string && (string[0]=='H' || string[0]=='h'))
    1125             :     {
    1126             :       char *endptr;
    1127             : 
    1128          10 :       string++;
    1129          10 :       val = strtol (string, &endptr, 10);
    1130          10 :       if (!*string || *endptr || openpgp_md_test_algo (val))
    1131           0 :         val = 0;
    1132             :     }
    1133             : 
    1134        1860 :   return val;
    1135             : }
    1136             : 
    1137             : 
    1138             : 
    1139             : const char *
    1140           4 : compress_algo_to_string(int algo)
    1141             : {
    1142           4 :   const char *s=NULL;
    1143             : 
    1144           4 :   switch(algo)
    1145             :     {
    1146             :     case COMPRESS_ALGO_NONE:
    1147           1 :       s=_("Uncompressed");
    1148           1 :       break;
    1149             : 
    1150             :     case COMPRESS_ALGO_ZIP:
    1151           1 :       s="ZIP";
    1152           1 :       break;
    1153             : 
    1154             :     case COMPRESS_ALGO_ZLIB:
    1155           1 :       s="ZLIB";
    1156           1 :       break;
    1157             : 
    1158             : #ifdef HAVE_BZIP2
    1159             :     case COMPRESS_ALGO_BZIP2:
    1160           1 :       s="BZIP2";
    1161           1 :       break;
    1162             : #endif
    1163             :     }
    1164             : 
    1165           4 :   return s;
    1166             : }
    1167             : 
    1168             : int
    1169           6 : string_to_compress_algo(const char *string)
    1170             : {
    1171             :   /* TRANSLATORS: See doc/TRANSLATE about this string. */
    1172           6 :   if(match_multistr(_("uncompressed|none"),string))
    1173           0 :     return 0;
    1174           6 :   else if(ascii_strcasecmp(string,"uncompressed")==0)
    1175           0 :     return 0;
    1176           6 :   else if(ascii_strcasecmp(string,"none")==0)
    1177           0 :     return 0;
    1178           6 :   else if(ascii_strcasecmp(string,"zip")==0)
    1179           0 :     return 1;
    1180           6 :   else if(ascii_strcasecmp(string,"zlib")==0)
    1181           0 :     return 2;
    1182             : #ifdef HAVE_BZIP2
    1183           6 :   else if(ascii_strcasecmp(string,"bzip2")==0)
    1184           0 :     return 3;
    1185             : #endif
    1186           6 :   else if(ascii_strcasecmp(string,"z0")==0)
    1187           0 :     return 0;
    1188           6 :   else if(ascii_strcasecmp(string,"z1")==0)
    1189           2 :     return 1;
    1190           4 :   else if(ascii_strcasecmp(string,"z2")==0)
    1191           2 :     return 2;
    1192             : #ifdef HAVE_BZIP2
    1193           2 :   else if(ascii_strcasecmp(string,"z3")==0)
    1194           2 :     return 3;
    1195             : #endif
    1196             :   else
    1197           0 :     return -1;
    1198             : }
    1199             : 
    1200             : int
    1201        1368 : check_compress_algo(int algo)
    1202             : {
    1203        1368 :   switch (algo)
    1204             :     {
    1205         248 :     case 0: return 0;
    1206             : #ifdef HAVE_ZIP
    1207             :     case 1:
    1208        1002 :     case 2: return 0;
    1209             : #endif
    1210             : #ifdef HAVE_BZIP2
    1211          11 :     case 3: return 0;
    1212             : #endif
    1213         107 :     default: return GPG_ERR_COMPR_ALGO;
    1214             :     }
    1215             : }
    1216             : 
    1217             : int
    1218         220 : default_cipher_algo(void)
    1219             : {
    1220         220 :   if(opt.def_cipher_algo)
    1221         210 :     return opt.def_cipher_algo;
    1222          10 :   else if(opt.personal_cipher_prefs)
    1223           0 :     return opt.personal_cipher_prefs[0].value;
    1224             :   else
    1225          10 :     return opt.s2k_cipher_algo;
    1226             : }
    1227             : 
    1228             : /* There is no default_digest_algo function, but see
    1229             :    sign.c:hash_for() */
    1230             : 
    1231             : int
    1232         510 : default_compress_algo(void)
    1233             : {
    1234         510 :   if(opt.compress_algo!=-1)
    1235           0 :     return opt.compress_algo;
    1236         510 :   else if(opt.personal_compress_prefs)
    1237           0 :     return opt.personal_compress_prefs[0].value;
    1238             :   else
    1239         510 :     return DEFAULT_COMPRESS_ALGO;
    1240             : }
    1241             : 
    1242             : const char *
    1243           0 : compliance_option_string(void)
    1244             : {
    1245           0 :   char *ver="???";
    1246             : 
    1247           0 :   switch(opt.compliance)
    1248             :     {
    1249           0 :     case CO_GNUPG:   return "--gnupg";
    1250           0 :     case CO_RFC4880: return "--openpgp";
    1251           0 :     case CO_RFC2440: return "--rfc2440";
    1252           0 :     case CO_PGP6:    return "--pgp6";
    1253           0 :     case CO_PGP7:    return "--pgp7";
    1254           0 :     case CO_PGP8:    return "--pgp8";
    1255             :     }
    1256             : 
    1257           0 :   return ver;
    1258             : }
    1259             : 
    1260             : void
    1261           0 : compliance_failure(void)
    1262             : {
    1263           0 :   char *ver="???";
    1264             : 
    1265           0 :   switch(opt.compliance)
    1266             :     {
    1267             :     case CO_GNUPG:
    1268           0 :       ver="GnuPG";
    1269           0 :       break;
    1270             : 
    1271             :     case CO_RFC4880:
    1272           0 :       ver="OpenPGP";
    1273           0 :       break;
    1274             : 
    1275             :     case CO_RFC2440:
    1276           0 :       ver="OpenPGP (older)";
    1277           0 :       break;
    1278             : 
    1279             :     case CO_PGP6:
    1280           0 :       ver="PGP 6.x";
    1281           0 :       break;
    1282             : 
    1283             :     case CO_PGP7:
    1284           0 :       ver="PGP 7.x";
    1285           0 :       break;
    1286             : 
    1287             :     case CO_PGP8:
    1288           0 :       ver="PGP 8.x";
    1289           0 :       break;
    1290             :     }
    1291             : 
    1292           0 :   log_info(_("this message may not be usable by %s\n"),ver);
    1293           0 :   opt.compliance=CO_GNUPG;
    1294           0 : }
    1295             : 
    1296             : /* Break a string into successive option pieces.  Accepts single word
    1297             :    options and key=value argument options. */
    1298             : char *
    1299        1500 : optsep(char **stringp)
    1300             : {
    1301             :   char *tok,*end;
    1302             : 
    1303        1500 :   tok=*stringp;
    1304        1500 :   if(tok)
    1305             :     {
    1306         750 :       end=strpbrk(tok," ,=");
    1307         750 :       if(end)
    1308             :         {
    1309           0 :           int sawequals=0;
    1310           0 :           char *ptr=end;
    1311             : 
    1312             :           /* what we need to do now is scan along starting with *end,
    1313             :              If the next character we see (ignoring spaces) is an =
    1314             :              sign, then there is an argument. */
    1315             : 
    1316           0 :           while(*ptr)
    1317             :             {
    1318           0 :               if(*ptr=='=')
    1319           0 :                 sawequals=1;
    1320           0 :               else if(*ptr!=' ')
    1321           0 :                 break;
    1322           0 :               ptr++;
    1323             :             }
    1324             : 
    1325             :           /* There is an argument, so grab that too.  At this point,
    1326             :              ptr points to the first character of the argument. */
    1327           0 :           if(sawequals)
    1328             :             {
    1329             :               /* Is it a quoted argument? */
    1330           0 :               if(*ptr=='"')
    1331             :                 {
    1332           0 :                   ptr++;
    1333           0 :                   end=strchr(ptr,'"');
    1334           0 :                   if(end)
    1335           0 :                     end++;
    1336             :                 }
    1337             :               else
    1338           0 :                 end=strpbrk(ptr," ,");
    1339             :             }
    1340             : 
    1341           0 :           if(end && *end)
    1342             :             {
    1343           0 :               *end='\0';
    1344           0 :               *stringp=end+1;
    1345             :             }
    1346             :           else
    1347           0 :             *stringp=NULL;
    1348             :         }
    1349             :       else
    1350         750 :         *stringp=NULL;
    1351             :     }
    1352             : 
    1353        1500 :   return tok;
    1354             : }
    1355             : 
    1356             : /* Breaks an option value into key and value.  Returns NULL if there
    1357             :    is no value.  Note that "string" is modified to remove the =value
    1358             :    part. */
    1359             : char *
    1360           0 : argsplit(char *string)
    1361             : {
    1362           0 :   char *equals,*arg=NULL;
    1363             : 
    1364           0 :   equals=strchr(string,'=');
    1365           0 :   if(equals)
    1366             :     {
    1367             :       char *quote,*space;
    1368             : 
    1369           0 :       *equals='\0';
    1370           0 :       arg=equals+1;
    1371             : 
    1372             :       /* Quoted arg? */
    1373           0 :       quote=strchr(arg,'"');
    1374           0 :       if(quote)
    1375             :         {
    1376           0 :           arg=quote+1;
    1377             : 
    1378           0 :           quote=strchr(arg,'"');
    1379           0 :           if(quote)
    1380           0 :             *quote='\0';
    1381             :         }
    1382             :       else
    1383             :         {
    1384             :           size_t spaces;
    1385             : 
    1386             :           /* Trim leading spaces off of the arg */
    1387           0 :           spaces=strspn(arg," ");
    1388           0 :           arg+=spaces;
    1389             :         }
    1390             : 
    1391             :       /* Trim tailing spaces off of the tag */
    1392           0 :       space=strchr(string,' ');
    1393           0 :       if(space)
    1394           0 :         *space='\0';
    1395             :     }
    1396             : 
    1397           0 :   return arg;
    1398             : }
    1399             : 
    1400             : /* Return the length of the initial token, leaving off any
    1401             :    argument. */
    1402             : static size_t
    1403        2625 : optlen(const char *s)
    1404             : {
    1405        2625 :   char *end=strpbrk(s," =");
    1406             : 
    1407        2625 :   if(end)
    1408           0 :     return end-s;
    1409             :   else
    1410        2625 :     return strlen(s);
    1411             : }
    1412             : 
    1413             : int
    1414         375 : parse_options(char *str,unsigned int *options,
    1415             :               struct parse_options *opts,int noisy)
    1416             : {
    1417             :   char *tok;
    1418             : 
    1419         375 :   if (str && !strcmp (str, "help"))
    1420             :     {
    1421           0 :       int i,maxlen=0;
    1422             : 
    1423             :       /* Figure out the longest option name so we can line these up
    1424             :          neatly. */
    1425           0 :       for(i=0;opts[i].name;i++)
    1426           0 :         if(opts[i].help && maxlen<strlen(opts[i].name))
    1427           0 :           maxlen=strlen(opts[i].name);
    1428             : 
    1429           0 :       for(i=0;opts[i].name;i++)
    1430           0 :         if(opts[i].help)
    1431           0 :           es_printf("%s%*s%s\n",opts[i].name,
    1432           0 :                     maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
    1433             : 
    1434           0 :       g10_exit(0);
    1435             :     }
    1436             : 
    1437        1125 :   while((tok=optsep(&str)))
    1438             :     {
    1439         375 :       int i,rev=0;
    1440         375 :       char *otok=tok;
    1441             : 
    1442         375 :       if(tok[0]=='\0')
    1443           0 :         continue;
    1444             : 
    1445         375 :       if(ascii_strncasecmp("no-",tok,3)==0)
    1446             :         {
    1447           0 :           rev=1;
    1448           0 :           tok+=3;
    1449             :         }
    1450             : 
    1451        2625 :       for(i=0;opts[i].name;i++)
    1452             :         {
    1453        2625 :           size_t toklen=optlen(tok);
    1454             : 
    1455        2625 :           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
    1456             :             {
    1457             :               /* We have a match, but it might be incomplete */
    1458         375 :               if(toklen!=strlen(opts[i].name))
    1459             :                 {
    1460             :                   int j;
    1461             : 
    1462           0 :                   for(j=i+1;opts[j].name;j++)
    1463             :                     {
    1464           0 :                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
    1465             :                         {
    1466           0 :                           if(noisy)
    1467           0 :                             log_info(_("ambiguous option '%s'\n"),otok);
    1468           0 :                           return 0;
    1469             :                         }
    1470             :                     }
    1471             :                 }
    1472             : 
    1473         375 :               if(rev)
    1474             :                 {
    1475           0 :                   *options&=~opts[i].bit;
    1476           0 :                   if(opts[i].value)
    1477           0 :                     *opts[i].value=NULL;
    1478             :                 }
    1479             :               else
    1480             :                 {
    1481         375 :                   *options|=opts[i].bit;
    1482         375 :                   if(opts[i].value)
    1483           0 :                     *opts[i].value=argsplit(tok);
    1484             :                 }
    1485         375 :               break;
    1486             :             }
    1487             :         }
    1488             : 
    1489         375 :       if(!opts[i].name)
    1490             :         {
    1491           0 :           if(noisy)
    1492           0 :             log_info(_("unknown option '%s'\n"),otok);
    1493           0 :           return 0;
    1494             :         }
    1495             :     }
    1496             : 
    1497         375 :   return 1;
    1498             : }
    1499             : 
    1500             : 
    1501             : /* Similar to access(2), but uses PATH to find the file. */
    1502             : int
    1503           0 : path_access(const char *file,int mode)
    1504             : {
    1505             :   char *envpath;
    1506           0 :   int ret=-1;
    1507             : 
    1508           0 :   envpath=getenv("PATH");
    1509             : 
    1510           0 :   if(!envpath
    1511             : #ifdef HAVE_DRIVE_LETTERS
    1512             :      || (((file[0]>='A' && file[0]<='Z')
    1513             :           || (file[0]>='a' && file[0]<='z'))
    1514             :          && file[1]==':')
    1515             : #else
    1516           0 :      || file[0]=='/'
    1517             : #endif
    1518             :      )
    1519           0 :     return access(file,mode);
    1520             :   else
    1521             :     {
    1522             :       /* At least as large as, but most often larger than we need. */
    1523           0 :       char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
    1524           0 :       char *split,*item,*path=xstrdup(envpath);
    1525             : 
    1526           0 :       split=path;
    1527             : 
    1528           0 :       while((item=strsep(&split,PATHSEP_S)))
    1529             :         {
    1530           0 :           strcpy(buffer,item);
    1531           0 :           strcat(buffer,"/");
    1532           0 :           strcat(buffer,file);
    1533           0 :           ret=access(buffer,mode);
    1534           0 :           if(ret==0)
    1535           0 :             break;
    1536             :         }
    1537             : 
    1538           0 :       xfree(path);
    1539           0 :       xfree(buffer);
    1540             :     }
    1541             : 
    1542           0 :   return ret;
    1543             : }
    1544             : 
    1545             : 
    1546             : 
    1547             : /* Return the number of public key parameters as used by OpenPGP.  */
    1548             : int
    1549       22740 : pubkey_get_npkey (pubkey_algo_t algo)
    1550             : {
    1551       22740 :   switch (algo)
    1552             :     {
    1553             :     case PUBKEY_ALGO_RSA:
    1554             :     case PUBKEY_ALGO_RSA_E:
    1555        3112 :     case PUBKEY_ALGO_RSA_S:     return 2;
    1556        7573 :     case PUBKEY_ALGO_ELGAMAL_E: return 3;
    1557        9816 :     case PUBKEY_ALGO_DSA:       return 4;
    1558         917 :     case PUBKEY_ALGO_ECDH:      return 3;
    1559        1201 :     case PUBKEY_ALGO_ECDSA:     return 2;
    1560           0 :     case PUBKEY_ALGO_ELGAMAL:   return 3;
    1561          50 :     case PUBKEY_ALGO_EDDSA:     return 2;
    1562             :     }
    1563          71 :   return 0;
    1564             : }
    1565             : 
    1566             : 
    1567             : /* Return the number of secret key parameters as used by OpenPGP.  */
    1568             : int
    1569        5906 : pubkey_get_nskey (pubkey_algo_t algo)
    1570             : {
    1571        5906 :   switch (algo)
    1572             :     {
    1573             :     case PUBKEY_ALGO_RSA:
    1574             :     case PUBKEY_ALGO_RSA_E:
    1575         767 :     case PUBKEY_ALGO_RSA_S:     return 6;
    1576        2274 :     case PUBKEY_ALGO_ELGAMAL_E: return 4;
    1577        2311 :     case PUBKEY_ALGO_DSA:       return 5;
    1578         274 :     case PUBKEY_ALGO_ECDH:      return 4;
    1579         270 :     case PUBKEY_ALGO_ECDSA:     return 3;
    1580           0 :     case PUBKEY_ALGO_ELGAMAL:   return 4;
    1581          10 :     case PUBKEY_ALGO_EDDSA:     return 3;
    1582             :     }
    1583           0 :   return 0;
    1584             : }
    1585             : 
    1586             : /* Temporary helper. */
    1587             : int
    1588       15468 : pubkey_get_nsig (pubkey_algo_t algo)
    1589             : {
    1590       15468 :   switch (algo)
    1591             :     {
    1592             :     case PUBKEY_ALGO_RSA:
    1593             :     case PUBKEY_ALGO_RSA_E:
    1594        2464 :     case PUBKEY_ALGO_RSA_S:     return 1;
    1595           0 :     case PUBKEY_ALGO_ELGAMAL_E: return 0;
    1596       11881 :     case PUBKEY_ALGO_DSA:       return 2;
    1597           0 :     case PUBKEY_ALGO_ECDH:      return 0;
    1598        1081 :     case PUBKEY_ALGO_ECDSA:     return 2;
    1599           0 :     case PUBKEY_ALGO_ELGAMAL:   return 2;
    1600          42 :     case PUBKEY_ALGO_EDDSA:     return 2;
    1601             :     }
    1602           0 :   return 0;
    1603             : }
    1604             : 
    1605             : 
    1606             : /* Temporary helper. */
    1607             : int
    1608        1046 : pubkey_get_nenc (pubkey_algo_t algo)
    1609             : {
    1610        1046 :   switch (algo)
    1611             :     {
    1612             :     case PUBKEY_ALGO_RSA:
    1613             :     case PUBKEY_ALGO_RSA_E:
    1614          34 :     case PUBKEY_ALGO_RSA_S:     return 1;
    1615         910 :     case PUBKEY_ALGO_ELGAMAL_E: return 2;
    1616           0 :     case PUBKEY_ALGO_DSA:       return 0;
    1617         102 :     case PUBKEY_ALGO_ECDH:      return 2;
    1618           0 :     case PUBKEY_ALGO_ECDSA:     return 0;
    1619           0 :     case PUBKEY_ALGO_ELGAMAL:   return 2;
    1620           0 :     case PUBKEY_ALGO_EDDSA:     return 0;
    1621             :     }
    1622           0 :   return 0;
    1623             : }
    1624             : 
    1625             : 
    1626             : /* Temporary helper. */
    1627             : unsigned int
    1628        1150 : pubkey_nbits( int algo, gcry_mpi_t *key )
    1629             : {
    1630             :   int rc, nbits;
    1631             :   gcry_sexp_t sexp;
    1632             : 
    1633        1150 :   if (algo == PUBKEY_ALGO_DSA
    1634         121 :       && key[0] && key[1] && key[2] && key[3])
    1635             :     {
    1636         363 :       rc = gcry_sexp_build (&sexp, NULL,
    1637             :                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
    1638         363 :                             key[0], key[1], key[2], key[3] );
    1639             :     }
    1640        1029 :   else if ((algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
    1641         710 :            && key[0] && key[1] && key[2])
    1642             :     {
    1643        1420 :       rc = gcry_sexp_build (&sexp, NULL,
    1644             :                             "(public-key(elg(p%m)(g%m)(y%m)))",
    1645        1420 :                             key[0], key[1], key[2] );
    1646             :     }
    1647         319 :   else if (is_RSA (algo)
    1648         142 :            && key[0] && key[1])
    1649             :     {
    1650         142 :       rc = gcry_sexp_build (&sexp, NULL,
    1651             :                             "(public-key(rsa(n%m)(e%m)))",
    1652         142 :                             key[0], key[1] );
    1653             :     }
    1654         177 :   else if ((algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
    1655           0 :             || algo == PUBKEY_ALGO_EDDSA)
    1656         177 :            && key[0] && key[1])
    1657         177 :     {
    1658         177 :       char *curve = openpgp_oid_to_str (key[0]);
    1659         177 :       if (!curve)
    1660           0 :         rc = gpg_error_from_syserror ();
    1661             :       else
    1662             :         {
    1663         177 :           rc = gcry_sexp_build (&sexp, NULL,
    1664             :                                 "(public-key(ecc(curve%s)(q%m)))",
    1665         177 :                                 curve, key[1]);
    1666         177 :           xfree (curve);
    1667             :         }
    1668             :     }
    1669             :   else
    1670           0 :     return 0;
    1671             : 
    1672        1150 :   if (rc)
    1673           0 :     BUG ();
    1674             : 
    1675        1150 :   nbits = gcry_pk_get_nbits (sexp);
    1676        1150 :   gcry_sexp_release (sexp);
    1677        1150 :   return nbits;
    1678             : }
    1679             : 
    1680             : 
    1681             : 
    1682             : int
    1683          76 : mpi_print (estream_t fp, gcry_mpi_t a, int mode)
    1684             : {
    1685          76 :   int n = 0;
    1686             :   size_t nwritten;
    1687             : 
    1688          76 :   if (!a)
    1689           0 :     return es_fprintf (fp, "[MPI_NULL]");
    1690          76 :   if (!mode)
    1691             :     {
    1692             :       unsigned int n1;
    1693          76 :       n1 = gcry_mpi_get_nbits(a);
    1694          76 :       n += es_fprintf (fp, "[%u bits]", n1);
    1695             :     }
    1696           0 :   else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
    1697             :     {
    1698             :       unsigned int nbits;
    1699           0 :       unsigned char *p = gcry_mpi_get_opaque (a, &nbits);
    1700           0 :       if (!p)
    1701           0 :         n += es_fprintf (fp, "[invalid opaque value]");
    1702             :       else
    1703             :         {
    1704           0 :           if (!es_write_hexstring (fp, p, (nbits + 7)/8, 0, &nwritten))
    1705           0 :             n += nwritten;
    1706             :         }
    1707             :     }
    1708             :   else
    1709             :     {
    1710             :       unsigned char *buffer;
    1711             :       size_t buflen;
    1712             : 
    1713           0 :       if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &buflen, a))
    1714           0 :         BUG ();
    1715           0 :       if (!es_write_hexstring (fp, buffer, buflen, 0, &nwritten))
    1716           0 :         n += nwritten;
    1717           0 :       gcry_free (buffer);
    1718             :     }
    1719          76 :   return n;
    1720             : }
    1721             : 
    1722             : 
    1723             : /* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
    1724             :    i.e.  04 <x> <y> */
    1725             : unsigned int
    1726         121 : ecdsa_qbits_from_Q (unsigned int qbits)
    1727             : {
    1728         121 :   if ((qbits%8) > 3)
    1729             :     {
    1730           0 :       log_error (_("ECDSA public key is expected to be in SEC encoding "
    1731             :                    "multiple of 8 bits\n"));
    1732           0 :       return 0;
    1733             :     }
    1734         121 :   qbits -= qbits%8;
    1735         121 :   qbits /= 2;
    1736         121 :   return qbits;
    1737             : }
    1738             : 
    1739             : 
    1740             : /* Ignore signatures and certifications made over certain digest
    1741             :  * algorithms by default, MD5 is considered weak.  This allows users
    1742             :  * to deprecate support for other algorithms as well.
    1743             :  */
    1744             : void
    1745        1828 : additional_weak_digest (const char* digestname)
    1746             : {
    1747        1828 :   struct weakhash *weak = NULL;
    1748        1828 :   const enum gcry_md_algos algo = string_to_digest_algo(digestname);
    1749             : 
    1750        1828 :   if (algo == GCRY_MD_NONE)
    1751             :     {
    1752           0 :       log_error (_("unknown weak digest '%s'\n"), digestname);
    1753           0 :       return;
    1754             :     }
    1755             : 
    1756             :   /* Check to ensure it's not already present.  */
    1757        1828 :   for (weak = opt.weak_digests; weak; weak = weak->next)
    1758           0 :     if (algo == weak->algo)
    1759           0 :       return;
    1760             : 
    1761             :   /* Add it to the head of the list.  */
    1762        1828 :   weak = xmalloc(sizeof(*weak));
    1763        1828 :   weak->algo = algo;
    1764        1828 :   weak->rejection_shown = 0;
    1765        1828 :   weak->next = opt.weak_digests;
    1766        1828 :   opt.weak_digests = weak;
    1767             : }

Generated by: LCOV version 1.11