LCOV - code coverage report
Current view: top level - g10 - misc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 305 676 45.1 %
Date: 2016-11-29 15:00:56 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 <https://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        1324 : 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        1324 : }
     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        2223 : 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        2223 :   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         779 : 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         779 :   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         396 : print_pubkey_algo_note (pubkey_algo_t algo)
     271             : {
     272         396 :   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         396 :   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         396 : }
     289             : 
     290             : void
     291         302 : print_cipher_algo_note (cipher_algo_t algo)
     292             : {
     293         302 :   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         302 : }
     305             : 
     306             : void
     307         141 : print_digest_algo_note (digest_algo_t algo)
     308             : {
     309         141 :   const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo);
     310             :   const struct weakhash *weak;
     311             : 
     312         141 :   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         282 :       for (weak = opt.weak_digests; weak != NULL; weak = weak->next)
     325         141 :         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         141 : }
     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       94301 : map_cipher_openpgp_to_gcry (cipher_algo_t algo)
     410             : {
     411       94301 :   switch (algo)
     412             :     {
     413           6 :     case CIPHER_ALGO_NONE:        return GCRY_CIPHER_NONE;
     414             : 
     415             : #ifdef GPG_USE_IDEA
     416         794 :     case CIPHER_ALGO_IDEA:        return GCRY_CIPHER_IDEA;
     417             : #else
     418             :     case CIPHER_ALGO_IDEA:        return 0;
     419             : #endif
     420             : 
     421         387 :     case CIPHER_ALGO_3DES:        return GCRY_CIPHER_3DES;
     422             : 
     423             : #ifdef GPG_USE_CAST5
     424        1023 :     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         200 :     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         430 :     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         331 :     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       89761 :     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         202 :     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         191 :     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         191 :     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         191 :     case CIPHER_ALGO_CAMELLIA256: return GCRY_CIPHER_CAMELLIA256;
     473             : #else
     474             :     case CIPHER_ALGO_CAMELLIA256: return 0;
     475             : #endif
     476             :     }
     477         594 :   return 0;
     478             : }
     479             : 
     480             : /* The inverse function of above.  */
     481             : static cipher_algo_t
     482         247 : map_cipher_gcry_to_openpgp (enum gcry_cipher_algos algo)
     483             : {
     484         247 :   switch (algo)
     485             :     {
     486          48 :     case GCRY_CIPHER_NONE:        return CIPHER_ALGO_NONE;
     487          19 :     case GCRY_CIPHER_IDEA:        return CIPHER_ALGO_IDEA;
     488          18 :     case GCRY_CIPHER_3DES:        return CIPHER_ALGO_3DES;
     489          18 :     case GCRY_CIPHER_CAST5:       return CIPHER_ALGO_CAST5;
     490          18 :     case GCRY_CIPHER_BLOWFISH:    return CIPHER_ALGO_BLOWFISH;
     491          18 :     case GCRY_CIPHER_AES:         return CIPHER_ALGO_AES;
     492          18 :     case GCRY_CIPHER_AES192:      return CIPHER_ALGO_AES192;
     493          18 :     case GCRY_CIPHER_AES256:      return CIPHER_ALGO_AES256;
     494          18 :     case GCRY_CIPHER_TWOFISH:     return CIPHER_ALGO_TWOFISH;
     495          18 :     case GCRY_CIPHER_CAMELLIA128: return CIPHER_ALGO_CAMELLIA128;
     496          18 :     case GCRY_CIPHER_CAMELLIA192: return CIPHER_ALGO_CAMELLIA192;
     497          18 :     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          33 : 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          33 :   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          27 :       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        3246 : openpgp_cipher_test_algo (cipher_algo_t algo)
     550             : {
     551             :   enum gcry_cipher_algos ga;
     552             : 
     553        3246 :   ga = map_cipher_openpgp_to_gcry (algo);
     554        3246 :   if (!ga)
     555         600 :     return gpg_error (GPG_ERR_CIPHER_ALGO);
     556             : 
     557        2646 :   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         349 : openpgp_cipher_algo_name (cipher_algo_t algo)
     565             : {
     566         349 :   switch (algo)
     567             :     {
     568           0 :     case CIPHER_ALGO_NONE:        break;
     569          12 :     case CIPHER_ALGO_IDEA:        return "IDEA";
     570          12 :     case CIPHER_ALGO_3DES:        return "3DES";
     571          14 :     case CIPHER_ALGO_CAST5:       return "CAST5";
     572          38 :     case CIPHER_ALGO_BLOWFISH:    return "BLOWFISH";
     573          63 :     case CIPHER_ALGO_AES:         return "AES";
     574          24 :     case CIPHER_ALGO_AES192:      return "AES192";
     575          34 :     case CIPHER_ALGO_AES256:      return "AES256";
     576          38 :     case CIPHER_ALGO_TWOFISH:     return "TWOFISH";
     577          38 :     case CIPHER_ALGO_CAMELLIA128: return "CAMELLIA128";
     578          38 :     case CIPHER_ALGO_CAMELLIA192: return "CAMELLIA192";
     579          38 :     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        5732 : openpgp_pk_test_algo (pubkey_algo_t algo)
     588             : {
     589        5732 :   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        6378 : openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
     597             : {
     598        6378 :   enum gcry_pk_algos ga = 0;
     599        6378 :   size_t use_buf = use;
     600             : 
     601        6378 :   switch (algo)
     602             :     {
     603             : #ifdef GPG_USE_RSA
     604        2479 :     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        2237 :     case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG;   break;
     614         874 :     case PUBKEY_ALGO_DSA:       ga = GCRY_PK_DSA;   break;
     615             : 
     616             : #ifdef GPG_USE_ECDH
     617         264 :     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          82 :     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          30 :     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           4 :       if (RFC2440)
     637           0 :         ga = GCRY_PK_ELG;
     638           4 :       break;
     639             :     }
     640        6378 :   if (!ga)
     641         412 :     return gpg_error (GPG_ERR_PUBKEY_ALGO);
     642             : 
     643             :   /* No check whether Libgcrypt has support for the algorithm.  */
     644        5966 :   return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
     645             : }
     646             : 
     647             : 
     648             : int
     649        5393 : openpgp_pk_algo_usage ( int algo )
     650             : {
     651        5393 :     int use = 0;
     652             : 
     653             :     /* They are hardwired in gpg 1.0. */
     654        5393 :     switch ( algo ) {
     655             :       case PUBKEY_ALGO_RSA:
     656        1413 :           use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
     657             :                  | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
     658        1413 :           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        1775 :           use = PUBKEY_USAGE_ENC;
     672        1775 :           break;
     673             :       case PUBKEY_ALGO_DSA:
     674        1775 :           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
     675        1775 :           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        5393 :     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         962 : openpgp_pk_algo_name (pubkey_algo_t algo)
     690             : {
     691         962 :   switch (algo)
     692             :     {
     693             :     case PUBKEY_ALGO_RSA:
     694             :     case PUBKEY_ALGO_RSA_E:
     695         103 :     case PUBKEY_ALGO_RSA_S:     return "RSA";
     696             :     case PUBKEY_ALGO_ELGAMAL:
     697         490 :     case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
     698         229 :     case PUBKEY_ALGO_DSA:       return "DSA";
     699          70 :     case PUBKEY_ALGO_ECDH:      return "ECDH";
     700          64 :     case PUBKEY_ALGO_ECDSA:     return "ECDSA";
     701           6 :     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       17660 : map_md_openpgp_to_gcry (digest_algo_t algo)
     711             : {
     712       17660 :   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        1083 :     case DIGEST_ALGO_SHA1:   return GCRY_MD_SHA1;
     721             : 
     722             : #ifdef GPG_USE_RMD160
     723         173 :     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         161 :     case DIGEST_ALGO_SHA224: return GCRY_MD_SHA224;
     730             : #else
     731             :     case DIGEST_ALGO_SHA224: return 0;
     732             : #endif
     733             : 
     734        1785 :     case DIGEST_ALGO_SHA256: return GCRY_MD_SHA256;
     735             : 
     736             : #ifdef GPG_USE_SHA384
     737         201 :     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         205 :     case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
     744             : #else
     745             :     case DIGEST_ALGO_SHA512: return 0;
     746             : #endif
     747             :     }
     748       13909 :   return 0;
     749             : }
     750             : 
     751             : 
     752             : /* Return 0 if ALGO is suitable and implemented OpenPGP hash
     753             :    algorithm.  */
     754             : int
     755        2926 : openpgp_md_test_algo (digest_algo_t algo)
     756             : {
     757             :   enum gcry_md_algos ga;
     758             : 
     759        2926 :   ga = map_md_openpgp_to_gcry (algo);
     760        2926 :   if (!ga)
     761         416 :     return gpg_error (GPG_ERR_DIGEST_ALGO);
     762             : 
     763        2510 :   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          55 : openpgp_md_algo_name (int algo)
     772             : {
     773          55 :   switch (algo)
     774             :     {
     775           0 :     case DIGEST_ALGO_MD5:    return "MD5";
     776          35 :     case DIGEST_ALGO_SHA1:   return "SHA1";
     777           4 :     case DIGEST_ALGO_RMD160: return "RIPEMD160";
     778           4 :     case DIGEST_ALGO_SHA256: return "SHA256";
     779           4 :     case DIGEST_ALGO_SHA384: return "SHA384";
     780           4 :     case DIGEST_ALGO_SHA512: return "SHA512";
     781           4 :     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         247 : string_to_cipher_algo (const char *string)
    1095             : {
    1096             :   int val;
    1097             : 
    1098         247 :   val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
    1099         247 :   if (!val && string && (string[0]=='S' || string[0]=='s'))
    1100             :     {
    1101             :       char *endptr;
    1102             : 
    1103          16 :       string++;
    1104          16 :       val = strtol (string, &endptr, 10);
    1105          16 :       if (!*string || *endptr || openpgp_cipher_test_algo (val))
    1106           0 :         val = 0;
    1107             :     }
    1108             : 
    1109         247 :   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        1276 : 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        1276 :   val = gcry_md_map_name (string);
    1124        1276 :   if (!val && string && (string[0]=='H' || string[0]=='h'))
    1125             :     {
    1126             :       char *endptr;
    1127             : 
    1128          20 :       string++;
    1129          20 :       val = strtol (string, &endptr, 10);
    1130          20 :       if (!*string || *endptr || openpgp_md_test_algo (val))
    1131           0 :         val = 0;
    1132             :     }
    1133             : 
    1134        1276 :   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          12 : string_to_compress_algo(const char *string)
    1170             : {
    1171             :   /* TRANSLATORS: See doc/TRANSLATE about this string. */
    1172          12 :   if(match_multistr(_("uncompressed|none"),string))
    1173           0 :     return 0;
    1174          12 :   else if(ascii_strcasecmp(string,"uncompressed")==0)
    1175           0 :     return 0;
    1176          12 :   else if(ascii_strcasecmp(string,"none")==0)
    1177           0 :     return 0;
    1178          12 :   else if(ascii_strcasecmp(string,"zip")==0)
    1179           0 :     return 1;
    1180          12 :   else if(ascii_strcasecmp(string,"zlib")==0)
    1181           0 :     return 2;
    1182             : #ifdef HAVE_BZIP2
    1183          12 :   else if(ascii_strcasecmp(string,"bzip2")==0)
    1184           0 :     return 3;
    1185             : #endif
    1186          12 :   else if(ascii_strcasecmp(string,"z0")==0)
    1187           0 :     return 0;
    1188          12 :   else if(ascii_strcasecmp(string,"z1")==0)
    1189           4 :     return 1;
    1190           8 :   else if(ascii_strcasecmp(string,"z2")==0)
    1191           4 :     return 2;
    1192             : #ifdef HAVE_BZIP2
    1193           4 :   else if(ascii_strcasecmp(string,"z3")==0)
    1194           4 :     return 3;
    1195             : #endif
    1196             :   else
    1197           0 :     return -1;
    1198             : }
    1199             : 
    1200             : int
    1201        1238 : check_compress_algo(int algo)
    1202             : {
    1203        1238 :   switch (algo)
    1204             :     {
    1205         248 :     case 0: return 0;
    1206             : #ifdef HAVE_ZIP
    1207             :     case 1:
    1208         869 :     case 2: return 0;
    1209             : #endif
    1210             : #ifdef HAVE_BZIP2
    1211          14 :     case 3: return 0;
    1212             : #endif
    1213         107 :     default: return GPG_ERR_COMPR_ALGO;
    1214             :     }
    1215             : }
    1216             : 
    1217             : int
    1218          55 : default_cipher_algo(void)
    1219             : {
    1220          55 :   if(opt.def_cipher_algo)
    1221          45 :     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         180 : default_compress_algo(void)
    1233             : {
    1234         180 :   if(opt.compress_algo!=-1)
    1235           0 :     return opt.compress_algo;
    1236         180 :   else if(opt.personal_compress_prefs)
    1237           0 :     return opt.personal_compress_prefs[0].value;
    1238             :   else
    1239         180 :     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           0 :     case CO_DE_VS:   return "--compliance=de-vs";
    1256             :     }
    1257             : 
    1258           0 :   return ver;
    1259             : }
    1260             : 
    1261             : void
    1262           0 : compliance_failure(void)
    1263             : {
    1264           0 :   char *ver="???";
    1265             : 
    1266           0 :   switch(opt.compliance)
    1267             :     {
    1268             :     case CO_GNUPG:
    1269           0 :       ver="GnuPG";
    1270           0 :       break;
    1271             : 
    1272             :     case CO_RFC4880:
    1273           0 :       ver="OpenPGP";
    1274           0 :       break;
    1275             : 
    1276             :     case CO_RFC2440:
    1277           0 :       ver="OpenPGP (older)";
    1278           0 :       break;
    1279             : 
    1280             :     case CO_PGP6:
    1281           0 :       ver="PGP 6.x";
    1282           0 :       break;
    1283             : 
    1284             :     case CO_PGP7:
    1285           0 :       ver="PGP 7.x";
    1286           0 :       break;
    1287             : 
    1288             :     case CO_PGP8:
    1289           0 :       ver="PGP 8.x";
    1290           0 :       break;
    1291             : 
    1292             :     case CO_DE_VS:
    1293           0 :       ver="DE-VS applications";
    1294           0 :       break;
    1295             :     }
    1296             : 
    1297           0 :   log_info(_("this message may not be usable by %s\n"),ver);
    1298           0 :   opt.compliance=CO_GNUPG;
    1299           0 : }
    1300             : 
    1301             : /* Break a string into successive option pieces.  Accepts single word
    1302             :    options and key=value argument options. */
    1303             : char *
    1304          12 : optsep(char **stringp)
    1305             : {
    1306             :   char *tok,*end;
    1307             : 
    1308          12 :   tok=*stringp;
    1309          12 :   if(tok)
    1310             :     {
    1311           6 :       end=strpbrk(tok," ,=");
    1312           6 :       if(end)
    1313             :         {
    1314           0 :           int sawequals=0;
    1315           0 :           char *ptr=end;
    1316             : 
    1317             :           /* what we need to do now is scan along starting with *end,
    1318             :              If the next character we see (ignoring spaces) is an =
    1319             :              sign, then there is an argument. */
    1320             : 
    1321           0 :           while(*ptr)
    1322             :             {
    1323           0 :               if(*ptr=='=')
    1324           0 :                 sawequals=1;
    1325           0 :               else if(*ptr!=' ')
    1326           0 :                 break;
    1327           0 :               ptr++;
    1328             :             }
    1329             : 
    1330             :           /* There is an argument, so grab that too.  At this point,
    1331             :              ptr points to the first character of the argument. */
    1332           0 :           if(sawequals)
    1333             :             {
    1334             :               /* Is it a quoted argument? */
    1335           0 :               if(*ptr=='"')
    1336             :                 {
    1337           0 :                   ptr++;
    1338           0 :                   end=strchr(ptr,'"');
    1339           0 :                   if(end)
    1340           0 :                     end++;
    1341             :                 }
    1342             :               else
    1343           0 :                 end=strpbrk(ptr," ,");
    1344             :             }
    1345             : 
    1346           0 :           if(end && *end)
    1347             :             {
    1348           0 :               *end='\0';
    1349           0 :               *stringp=end+1;
    1350             :             }
    1351             :           else
    1352           0 :             *stringp=NULL;
    1353             :         }
    1354             :       else
    1355           6 :         *stringp=NULL;
    1356             :     }
    1357             : 
    1358          12 :   return tok;
    1359             : }
    1360             : 
    1361             : /* Breaks an option value into key and value.  Returns NULL if there
    1362             :    is no value.  Note that "string" is modified to remove the =value
    1363             :    part. */
    1364             : char *
    1365           0 : argsplit(char *string)
    1366             : {
    1367           0 :   char *equals,*arg=NULL;
    1368             : 
    1369           0 :   equals=strchr(string,'=');
    1370           0 :   if(equals)
    1371             :     {
    1372             :       char *quote,*space;
    1373             : 
    1374           0 :       *equals='\0';
    1375           0 :       arg=equals+1;
    1376             : 
    1377             :       /* Quoted arg? */
    1378           0 :       quote=strchr(arg,'"');
    1379           0 :       if(quote)
    1380             :         {
    1381           0 :           arg=quote+1;
    1382             : 
    1383           0 :           quote=strchr(arg,'"');
    1384           0 :           if(quote)
    1385           0 :             *quote='\0';
    1386             :         }
    1387             :       else
    1388             :         {
    1389             :           size_t spaces;
    1390             : 
    1391             :           /* Trim leading spaces off of the arg */
    1392           0 :           spaces=strspn(arg," ");
    1393           0 :           arg+=spaces;
    1394             :         }
    1395             : 
    1396             :       /* Trim tailing spaces off of the tag */
    1397           0 :       space=strchr(string,' ');
    1398           0 :       if(space)
    1399           0 :         *space='\0';
    1400             :     }
    1401             : 
    1402           0 :   return arg;
    1403             : }
    1404             : 
    1405             : /* Return the length of the initial token, leaving off any
    1406             :    argument. */
    1407             : static size_t
    1408          21 : optlen(const char *s)
    1409             : {
    1410          21 :   char *end=strpbrk(s," =");
    1411             : 
    1412          21 :   if(end)
    1413           0 :     return end-s;
    1414             :   else
    1415          21 :     return strlen(s);
    1416             : }
    1417             : 
    1418             : int
    1419           3 : parse_options(char *str,unsigned int *options,
    1420             :               struct parse_options *opts,int noisy)
    1421             : {
    1422             :   char *tok;
    1423             : 
    1424           3 :   if (str && !strcmp (str, "help"))
    1425             :     {
    1426           0 :       int i,maxlen=0;
    1427             : 
    1428             :       /* Figure out the longest option name so we can line these up
    1429             :          neatly. */
    1430           0 :       for(i=0;opts[i].name;i++)
    1431           0 :         if(opts[i].help && maxlen<strlen(opts[i].name))
    1432           0 :           maxlen=strlen(opts[i].name);
    1433             : 
    1434           0 :       for(i=0;opts[i].name;i++)
    1435           0 :         if(opts[i].help)
    1436           0 :           es_printf("%s%*s%s\n",opts[i].name,
    1437           0 :                     maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
    1438             : 
    1439           0 :       g10_exit(0);
    1440             :     }
    1441             : 
    1442           9 :   while((tok=optsep(&str)))
    1443             :     {
    1444           3 :       int i,rev=0;
    1445           3 :       char *otok=tok;
    1446             : 
    1447           3 :       if(tok[0]=='\0')
    1448           0 :         continue;
    1449             : 
    1450           3 :       if(ascii_strncasecmp("no-",tok,3)==0)
    1451             :         {
    1452           0 :           rev=1;
    1453           0 :           tok+=3;
    1454             :         }
    1455             : 
    1456          21 :       for(i=0;opts[i].name;i++)
    1457             :         {
    1458          21 :           size_t toklen=optlen(tok);
    1459             : 
    1460          21 :           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
    1461             :             {
    1462             :               /* We have a match, but it might be incomplete */
    1463           3 :               if(toklen!=strlen(opts[i].name))
    1464             :                 {
    1465             :                   int j;
    1466             : 
    1467           0 :                   for(j=i+1;opts[j].name;j++)
    1468             :                     {
    1469           0 :                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
    1470             :                         {
    1471           0 :                           if(noisy)
    1472           0 :                             log_info(_("ambiguous option '%s'\n"),otok);
    1473           0 :                           return 0;
    1474             :                         }
    1475             :                     }
    1476             :                 }
    1477             : 
    1478           3 :               if(rev)
    1479             :                 {
    1480           0 :                   *options&=~opts[i].bit;
    1481           0 :                   if(opts[i].value)
    1482           0 :                     *opts[i].value=NULL;
    1483             :                 }
    1484             :               else
    1485             :                 {
    1486           3 :                   *options|=opts[i].bit;
    1487           3 :                   if(opts[i].value)
    1488           0 :                     *opts[i].value=argsplit(tok);
    1489             :                 }
    1490           3 :               break;
    1491             :             }
    1492             :         }
    1493             : 
    1494           3 :       if(!opts[i].name)
    1495             :         {
    1496           0 :           if(noisy)
    1497           0 :             log_info(_("unknown option '%s'\n"),otok);
    1498           0 :           return 0;
    1499             :         }
    1500             :     }
    1501             : 
    1502           3 :   return 1;
    1503             : }
    1504             : 
    1505             : 
    1506             : /* Similar to access(2), but uses PATH to find the file. */
    1507             : int
    1508           0 : path_access(const char *file,int mode)
    1509             : {
    1510             :   char *envpath;
    1511           0 :   int ret=-1;
    1512             : 
    1513           0 :   envpath=getenv("PATH");
    1514             : 
    1515           0 :   if(!envpath
    1516             : #ifdef HAVE_DRIVE_LETTERS
    1517             :      || (((file[0]>='A' && file[0]<='Z')
    1518             :           || (file[0]>='a' && file[0]<='z'))
    1519             :          && file[1]==':')
    1520             : #else
    1521           0 :      || file[0]=='/'
    1522             : #endif
    1523             :      )
    1524           0 :     return access(file,mode);
    1525             :   else
    1526             :     {
    1527             :       /* At least as large as, but most often larger than we need. */
    1528           0 :       char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
    1529           0 :       char *split,*item,*path=xstrdup(envpath);
    1530             : 
    1531           0 :       split=path;
    1532             : 
    1533           0 :       while((item=strsep(&split,PATHSEP_S)))
    1534             :         {
    1535           0 :           strcpy(buffer,item);
    1536           0 :           strcat(buffer,"/");
    1537           0 :           strcat(buffer,file);
    1538           0 :           ret=access(buffer,mode);
    1539           0 :           if(ret==0)
    1540           0 :             break;
    1541             :         }
    1542             : 
    1543           0 :       xfree(path);
    1544           0 :       xfree(buffer);
    1545             :     }
    1546             : 
    1547           0 :   return ret;
    1548             : }
    1549             : 
    1550             : 
    1551             : 
    1552             : /* Return the number of public key parameters as used by OpenPGP.  */
    1553             : int
    1554       29381 : pubkey_get_npkey (pubkey_algo_t algo)
    1555             : {
    1556       29381 :   switch (algo)
    1557             :     {
    1558             :     case PUBKEY_ALGO_RSA:
    1559             :     case PUBKEY_ALGO_RSA_E:
    1560        9165 :     case PUBKEY_ALGO_RSA_S:     return 2;
    1561        7674 :     case PUBKEY_ALGO_ELGAMAL_E: return 3;
    1562       10140 :     case PUBKEY_ALGO_DSA:       return 4;
    1563         917 :     case PUBKEY_ALGO_ECDH:      return 3;
    1564        1249 :     case PUBKEY_ALGO_ECDSA:     return 2;
    1565           0 :     case PUBKEY_ALGO_ELGAMAL:   return 3;
    1566          52 :     case PUBKEY_ALGO_EDDSA:     return 2;
    1567             :     }
    1568         184 :   return 0;
    1569             : }
    1570             : 
    1571             : 
    1572             : /* Return the number of secret key parameters as used by OpenPGP.  */
    1573             : int
    1574        7707 : pubkey_get_nskey (pubkey_algo_t algo)
    1575             : {
    1576        7707 :   switch (algo)
    1577             :     {
    1578             :     case PUBKEY_ALGO_RSA:
    1579             :     case PUBKEY_ALGO_RSA_E:
    1580        2511 :     case PUBKEY_ALGO_RSA_S:     return 6;
    1581        2303 :     case PUBKEY_ALGO_ELGAMAL_E: return 4;
    1582        2339 :     case PUBKEY_ALGO_DSA:       return 5;
    1583         274 :     case PUBKEY_ALGO_ECDH:      return 4;
    1584         270 :     case PUBKEY_ALGO_ECDSA:     return 3;
    1585           0 :     case PUBKEY_ALGO_ELGAMAL:   return 4;
    1586          10 :     case PUBKEY_ALGO_EDDSA:     return 3;
    1587             :     }
    1588           0 :   return 0;
    1589             : }
    1590             : 
    1591             : /* Temporary helper. */
    1592             : int
    1593       19611 : pubkey_get_nsig (pubkey_algo_t algo)
    1594             : {
    1595       19611 :   switch (algo)
    1596             :     {
    1597             :     case PUBKEY_ALGO_RSA:
    1598             :     case PUBKEY_ALGO_RSA_E:
    1599        6471 :     case PUBKEY_ALGO_RSA_S:     return 1;
    1600           0 :     case PUBKEY_ALGO_ELGAMAL_E: return 0;
    1601       12017 :     case PUBKEY_ALGO_DSA:       return 2;
    1602           0 :     case PUBKEY_ALGO_ECDH:      return 0;
    1603        1081 :     case PUBKEY_ALGO_ECDSA:     return 2;
    1604           0 :     case PUBKEY_ALGO_ELGAMAL:   return 2;
    1605          42 :     case PUBKEY_ALGO_EDDSA:     return 2;
    1606             :     }
    1607           0 :   return 0;
    1608             : }
    1609             : 
    1610             : 
    1611             : /* Temporary helper. */
    1612             : int
    1613        1052 : pubkey_get_nenc (pubkey_algo_t algo)
    1614             : {
    1615        1052 :   switch (algo)
    1616             :     {
    1617             :     case PUBKEY_ALGO_RSA:
    1618             :     case PUBKEY_ALGO_RSA_E:
    1619          34 :     case PUBKEY_ALGO_RSA_S:     return 1;
    1620         916 :     case PUBKEY_ALGO_ELGAMAL_E: return 2;
    1621           0 :     case PUBKEY_ALGO_DSA:       return 0;
    1622         102 :     case PUBKEY_ALGO_ECDH:      return 2;
    1623           0 :     case PUBKEY_ALGO_ECDSA:     return 0;
    1624           0 :     case PUBKEY_ALGO_ELGAMAL:   return 2;
    1625           0 :     case PUBKEY_ALGO_EDDSA:     return 0;
    1626             :     }
    1627           0 :   return 0;
    1628             : }
    1629             : 
    1630             : 
    1631             : /* Temporary helper. */
    1632             : unsigned int
    1633        1291 : pubkey_nbits( int algo, gcry_mpi_t *key )
    1634             : {
    1635             :   int rc, nbits;
    1636             :   gcry_sexp_t sexp;
    1637             : 
    1638        1291 :   if (algo == PUBKEY_ALGO_DSA
    1639         121 :       && key[0] && key[1] && key[2] && key[3])
    1640             :     {
    1641         363 :       rc = gcry_sexp_build (&sexp, NULL,
    1642             :                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
    1643         363 :                             key[0], key[1], key[2], key[3] );
    1644             :     }
    1645        1170 :   else if ((algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
    1646         716 :            && key[0] && key[1] && key[2])
    1647             :     {
    1648        1432 :       rc = gcry_sexp_build (&sexp, NULL,
    1649             :                             "(public-key(elg(p%m)(g%m)(y%m)))",
    1650        1432 :                             key[0], key[1], key[2] );
    1651             :     }
    1652         454 :   else if (is_RSA (algo)
    1653         277 :            && key[0] && key[1])
    1654             :     {
    1655         277 :       rc = gcry_sexp_build (&sexp, NULL,
    1656             :                             "(public-key(rsa(n%m)(e%m)))",
    1657         277 :                             key[0], key[1] );
    1658             :     }
    1659         177 :   else if ((algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
    1660           0 :             || algo == PUBKEY_ALGO_EDDSA)
    1661         177 :            && key[0] && key[1])
    1662         177 :     {
    1663         177 :       char *curve = openpgp_oid_to_str (key[0]);
    1664         177 :       if (!curve)
    1665           0 :         rc = gpg_error_from_syserror ();
    1666             :       else
    1667             :         {
    1668         177 :           rc = gcry_sexp_build (&sexp, NULL,
    1669             :                                 "(public-key(ecc(curve%s)(q%m)))",
    1670         177 :                                 curve, key[1]);
    1671         177 :           xfree (curve);
    1672             :         }
    1673             :     }
    1674             :   else
    1675           0 :     return 0;
    1676             : 
    1677        1291 :   if (rc)
    1678           0 :     BUG ();
    1679             : 
    1680        1291 :   nbits = gcry_pk_get_nbits (sexp);
    1681        1291 :   gcry_sexp_release (sexp);
    1682        1291 :   return nbits;
    1683             : }
    1684             : 
    1685             : 
    1686             : 
    1687             : int
    1688          76 : mpi_print (estream_t fp, gcry_mpi_t a, int mode)
    1689             : {
    1690          76 :   int n = 0;
    1691             :   size_t nwritten;
    1692             : 
    1693          76 :   if (!a)
    1694           0 :     return es_fprintf (fp, "[MPI_NULL]");
    1695          76 :   if (!mode)
    1696             :     {
    1697             :       unsigned int n1;
    1698          76 :       n1 = gcry_mpi_get_nbits(a);
    1699          76 :       n += es_fprintf (fp, "[%u bits]", n1);
    1700             :     }
    1701           0 :   else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
    1702             :     {
    1703             :       unsigned int nbits;
    1704           0 :       unsigned char *p = gcry_mpi_get_opaque (a, &nbits);
    1705           0 :       if (!p)
    1706           0 :         n += es_fprintf (fp, "[invalid opaque value]");
    1707             :       else
    1708             :         {
    1709           0 :           if (!es_write_hexstring (fp, p, (nbits + 7)/8, 0, &nwritten))
    1710           0 :             n += nwritten;
    1711             :         }
    1712             :     }
    1713             :   else
    1714             :     {
    1715             :       unsigned char *buffer;
    1716             :       size_t buflen;
    1717             : 
    1718           0 :       if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &buflen, a))
    1719           0 :         BUG ();
    1720           0 :       if (!es_write_hexstring (fp, buffer, buflen, 0, &nwritten))
    1721           0 :         n += nwritten;
    1722           0 :       gcry_free (buffer);
    1723             :     }
    1724          76 :   return n;
    1725             : }
    1726             : 
    1727             : 
    1728             : /* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
    1729             :    i.e.  04 <x> <y> */
    1730             : unsigned int
    1731         121 : ecdsa_qbits_from_Q (unsigned int qbits)
    1732             : {
    1733         121 :   if ((qbits%8) > 3)
    1734             :     {
    1735           0 :       log_error (_("ECDSA public key is expected to be in SEC encoding "
    1736             :                    "multiple of 8 bits\n"));
    1737           0 :       return 0;
    1738             :     }
    1739         121 :   qbits -= qbits%8;
    1740         121 :   qbits /= 2;
    1741         121 :   return qbits;
    1742             : }
    1743             : 
    1744             : 
    1745             : /* Ignore signatures and certifications made over certain digest
    1746             :  * algorithms by default, MD5 is considered weak.  This allows users
    1747             :  * to deprecate support for other algorithms as well.
    1748             :  */
    1749             : void
    1750        1228 : additional_weak_digest (const char* digestname)
    1751             : {
    1752        1228 :   struct weakhash *weak = NULL;
    1753        1228 :   const enum gcry_md_algos algo = string_to_digest_algo(digestname);
    1754             : 
    1755        1228 :   if (algo == GCRY_MD_NONE)
    1756             :     {
    1757           0 :       log_error (_("unknown weak digest '%s'\n"), digestname);
    1758           0 :       return;
    1759             :     }
    1760             : 
    1761             :   /* Check to ensure it's not already present.  */
    1762        1228 :   for (weak = opt.weak_digests; weak; weak = weak->next)
    1763           0 :     if (algo == weak->algo)
    1764           0 :       return;
    1765             : 
    1766             :   /* Add it to the head of the list.  */
    1767        1228 :   weak = xmalloc(sizeof(*weak));
    1768        1228 :   weak->algo = algo;
    1769        1228 :   weak->rejection_shown = 0;
    1770        1228 :   weak->next = opt.weak_digests;
    1771        1228 :   opt.weak_digests = weak;
    1772             : }

Generated by: LCOV version 1.11