LCOV - code coverage report
Current view: top level - g10 - misc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 262 657 39.9 %
Date: 2015-11-05 17:10:59 Functions: 34 51 66.7 %

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

Generated by: LCOV version 1.11