LCOV - code coverage report
Current view: top level - sm - qualified.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 130 0.0 %
Date: 2016-09-12 12:29:17 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* qualified.c - Routines related to qualified signatures
       2             :  * Copyright (C) 2005, 2007 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : #include <stdarg.h>
      25             : #include <assert.h>
      26             : #include <errno.h>
      27             : 
      28             : #include "gpgsm.h"
      29             : #include "i18n.h"
      30             : #include <ksba.h>
      31             : 
      32             : 
      33             : /* We open the file only once and keep the open file pointer as well
      34             :    as the name of the file here.  Note that, a listname not equal to
      35             :    NULL indicates that this module has been intialized and if the
      36             :    LISTFP is also NULL, no list of qualified signatures exists. */
      37             : static char *listname;
      38             : static FILE *listfp;
      39             : 
      40             : 
      41             : /* Read the trustlist and return entry by entry.  KEY must point to a
      42             :    buffer of at least 41 characters. COUNTRY shall be a buffer of at
      43             :    least 3 characters to receive the country code of that qualified
      44             :    signature (i.e. "de" for German and "be" for Belgium).
      45             : 
      46             :    Reading a valid entry returns 0, EOF is indicated by GPG_ERR_EOF
      47             :    and any other error condition is indicated by the appropriate error
      48             :    code. */
      49             : static gpg_error_t
      50           0 : read_list (char *key, char *country, int *lnr)
      51             : {
      52             :   gpg_error_t err;
      53             :   int c, i, j;
      54             :   char *p, line[256];
      55             : 
      56           0 :   *key = 0;
      57           0 :   *country = 0;
      58             : 
      59           0 :   if (!listname)
      60             :     {
      61           0 :       listname = make_filename (gnupg_datadir (), "qualified.txt", NULL);
      62           0 :       listfp = fopen (listname, "r");
      63           0 :       if (!listfp && errno != ENOENT)
      64             :         {
      65           0 :           err = gpg_error_from_syserror ();
      66           0 :           log_error (_("can't open '%s': %s\n"), listname, gpg_strerror (err));
      67           0 :           return err;
      68             :         }
      69             :     }
      70             : 
      71           0 :   if (!listfp)
      72           0 :     return gpg_error (GPG_ERR_EOF);
      73             : 
      74             :   do
      75             :     {
      76           0 :       if (!fgets (line, DIM(line)-1, listfp) )
      77             :         {
      78           0 :           if (feof (listfp))
      79           0 :             return gpg_error (GPG_ERR_EOF);
      80           0 :           return gpg_error_from_syserror ();
      81             :         }
      82             : 
      83           0 :       if (!*line || line[strlen(line)-1] != '\n')
      84             :         {
      85             :           /* Eat until end of line. */
      86           0 :           while ( (c=getc (listfp)) != EOF && c != '\n')
      87             :             ;
      88           0 :           return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
      89             :                                  : GPG_ERR_INCOMPLETE_LINE);
      90             :         }
      91           0 :       ++*lnr;
      92             : 
      93             :       /* Allow for empty lines and spaces */
      94           0 :       for (p=line; spacep (p); p++)
      95             :         ;
      96             :     }
      97           0 :   while (!*p || *p == '\n' || *p == '#');
      98             : 
      99           0 :   for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
     100           0 :     if ( p[i] != ':' )
     101           0 :       key[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
     102           0 :   key[j] = 0;
     103           0 :   if (j != 40 || !(spacep (p+i) || p[i] == '\n'))
     104             :     {
     105           0 :       log_error (_("invalid formatted fingerprint in '%s', line %d\n"),
     106             :                  listname, *lnr);
     107           0 :       return gpg_error (GPG_ERR_BAD_DATA);
     108             :     }
     109           0 :   assert (p[i]);
     110           0 :   i++;
     111           0 :   while (spacep (p+i))
     112           0 :     i++;
     113           0 :   if ( p[i] >= 'a' && p[i] <= 'z'
     114           0 :        && p[i+1] >= 'a' && p[i+1] <= 'z'
     115           0 :        && (spacep (p+i+2) || p[i+2] == '\n'))
     116             :     {
     117           0 :       country[0] = p[i];
     118           0 :       country[1] = p[i+1];
     119           0 :       country[2] = 0;
     120             :     }
     121             :   else
     122             :     {
     123           0 :       log_error (_("invalid country code in '%s', line %d\n"), listname, *lnr);
     124           0 :       return gpg_error (GPG_ERR_BAD_DATA);
     125             :     }
     126             : 
     127           0 :   return 0;
     128             : }
     129             : 
     130             : 
     131             : 
     132             : 
     133             : /* Check whether the certificate CERT is included in the list of
     134             :    qualified certificates.  This list is similar to the "trustlist.txt"
     135             :    as maintained by gpg-agent and includes fingerprints of root
     136             :    certificates to be used for qualified (legally binding like
     137             :    handwritten) signatures.  We keep this list system wide and not
     138             :    per user because it is not a decision of the user.
     139             : 
     140             :    Returns: 0 if the certificate is included.  GPG_ERR_NOT_FOUND if it
     141             :    is not in the list or any other error (e.g. if no list of
     142             :    qualified signatures is available.  If COUNTRY has not been passed
     143             :    as NULL a string witha maximum length of 2 will be copied into it;
     144             :    thus the caller needs to provide a buffer of length 3. */
     145             : gpg_error_t
     146           0 : gpgsm_is_in_qualified_list (ctrl_t ctrl, ksba_cert_t cert, char *country)
     147             : {
     148             :   gpg_error_t err;
     149             :   char *fpr;
     150             :   char key[41];
     151             :   char mycountry[3];
     152           0 :   int lnr = 0;
     153             : 
     154             :   (void)ctrl;
     155             : 
     156           0 :   if (country)
     157           0 :     *country = 0;
     158             : 
     159           0 :   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
     160           0 :   if (!fpr)
     161           0 :     return gpg_error (GPG_ERR_GENERAL);
     162             : 
     163           0 :   if (listfp)
     164             :     {
     165             :       /* W32ce has no rewind, thus we use the equivalent code.  */
     166           0 :       fseek (listfp, 0, SEEK_SET);
     167           0 :       clearerr (listfp);
     168             :     }
     169           0 :   while (!(err = read_list (key, mycountry, &lnr)))
     170             :     {
     171           0 :       if (!strcmp (key, fpr))
     172           0 :         break;
     173             :     }
     174           0 :   if (gpg_err_code (err) == GPG_ERR_EOF)
     175           0 :     err = gpg_error (GPG_ERR_NOT_FOUND);
     176             : 
     177           0 :   if (!err && country)
     178           0 :     strcpy (country, mycountry);
     179             : 
     180           0 :   xfree (fpr);
     181           0 :   return err;
     182             : }
     183             : 
     184             : 
     185             : /* We know that CERT is a qualified certificate.  Ask the user for
     186             :    consent to actually create a signature using this certificate.
     187             :    Returns: 0 for yes, GPG_ERR_CANCEL for no or any other error
     188             :    code. */
     189             : gpg_error_t
     190           0 : gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert)
     191             : {
     192             :   gpg_error_t err;
     193             :   char *name, *subject, *buffer, *p;
     194             :   const char *s;
     195           0 :   char *orig_codeset = NULL;
     196             : 
     197           0 :   name = ksba_cert_get_subject (cert, 0);
     198           0 :   if (!name)
     199           0 :     return gpg_error (GPG_ERR_GENERAL);
     200           0 :   subject = gpgsm_format_name2 (name, 0);
     201           0 :   ksba_free (name); name = NULL;
     202             : 
     203           0 :   orig_codeset = i18n_switchto_utf8 ();
     204             : 
     205           0 :   if (asprintf (&name,
     206           0 :                 _("You are about to create a signature using your "
     207             :                   "certificate:\n"
     208             :                   "\"%s\"\n"
     209             :                   "This will create a qualified signature by law "
     210             :                   "equated to a handwritten signature.\n\n%s%s"
     211             :                   "Are you really sure that you want to do this?"),
     212             :                 subject? subject:"?",
     213           0 :                 opt.qualsig_approval?
     214             :                 "":
     215             :                 _("Note, that this software is not officially approved "
     216             :                   "to create or verify such signatures.\n"),
     217           0 :                 opt.qualsig_approval? "":"\n"
     218             :                 ) < 0 )
     219           0 :     err = gpg_error_from_syserror ();
     220             :   else
     221           0 :     err = 0;
     222             : 
     223           0 :   i18n_switchback (orig_codeset);
     224           0 :   xfree (subject);
     225             : 
     226           0 :   if (err)
     227           0 :     return err;
     228             : 
     229           0 :   buffer = p = xtrymalloc (strlen (name) * 3 + 1);
     230           0 :   if (!buffer)
     231             :     {
     232           0 :       err = gpg_error_from_syserror ();
     233           0 :       free (name);
     234           0 :       return err;
     235             :     }
     236           0 :   for (s=name; *s; s++)
     237             :     {
     238           0 :       if (*s < ' ' || *s == '+')
     239             :         {
     240           0 :           sprintf (p, "%%%02X", *(unsigned char *)s);
     241           0 :           p += 3;
     242             :         }
     243           0 :       else if (*s == ' ')
     244           0 :         *p++ = '+';
     245             :       else
     246           0 :         *p++ = *s;
     247             :     }
     248           0 :   *p = 0;
     249           0 :   free (name);
     250             : 
     251             : 
     252           0 :   err = gpgsm_agent_get_confirmation (ctrl, buffer);
     253             : 
     254           0 :   xfree (buffer);
     255           0 :   return err;
     256             : }
     257             : 
     258             : 
     259             : /* Popup a prompt to inform the user that the signature created is not
     260             :    a qualified one.  This is of course only done if we know that we
     261             :    have been approved. */
     262             : gpg_error_t
     263           0 : gpgsm_not_qualified_warning (ctrl_t ctrl, ksba_cert_t cert)
     264             : {
     265             :   gpg_error_t err;
     266             :   char *name, *subject, *buffer, *p;
     267             :   const char *s;
     268             :   char *orig_codeset;
     269             : 
     270           0 :   if (!opt.qualsig_approval)
     271           0 :     return 0;
     272             : 
     273           0 :   name = ksba_cert_get_subject (cert, 0);
     274           0 :   if (!name)
     275           0 :     return gpg_error (GPG_ERR_GENERAL);
     276           0 :   subject = gpgsm_format_name2 (name, 0);
     277           0 :   ksba_free (name); name = NULL;
     278             : 
     279           0 :   orig_codeset = i18n_switchto_utf8 ();
     280             : 
     281           0 :   if (asprintf (&name,
     282           0 :                 _("You are about to create a signature using your "
     283             :                   "certificate:\n"
     284             :                   "\"%s\"\n"
     285             :                   "Note, that this certificate will NOT create a "
     286             :                   "qualified signature!"),
     287             :                 subject? subject:"?") < 0 )
     288           0 :     err = gpg_error_from_syserror ();
     289             :   else
     290           0 :     err = 0;
     291             : 
     292           0 :   i18n_switchback (orig_codeset);
     293           0 :   xfree (subject);
     294             : 
     295           0 :   if (err)
     296           0 :     return err;
     297             : 
     298           0 :   buffer = p = xtrymalloc (strlen (name) * 3 + 1);
     299           0 :   if (!buffer)
     300             :     {
     301           0 :       err = gpg_error_from_syserror ();
     302           0 :       free (name);
     303           0 :       return err;
     304             :     }
     305           0 :   for (s=name; *s; s++)
     306             :     {
     307           0 :       if (*s < ' ' || *s == '+')
     308             :         {
     309           0 :           sprintf (p, "%%%02X", *(unsigned char *)s);
     310           0 :           p += 3;
     311             :         }
     312           0 :       else if (*s == ' ')
     313           0 :         *p++ = '+';
     314             :       else
     315           0 :         *p++ = *s;
     316             :     }
     317           0 :   *p = 0;
     318           0 :   free (name);
     319             : 
     320             : 
     321           0 :   err = gpgsm_agent_get_confirmation (ctrl, buffer);
     322             : 
     323           0 :   xfree (buffer);
     324           0 :   return err;
     325             : }

Generated by: LCOV version 1.11