2008-02-01 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / sm / qualified.c
blob507c1517f667380c75308abe80a6dc380c848542
1 /* qualified.c - Routines related to qualified signatures
2 * Copyright (C) 2005, 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
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>
28 #include "gpgsm.h"
29 #include "i18n.h"
30 #include <ksba.h>
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;
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).
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 read_list (char *key, char *country, int *lnr)
52 gpg_error_t err;
53 int c, i, j;
54 char *p, line[256];
56 *key = 0;
57 *country = 0;
59 if (!listname)
61 listname = make_filename (gnupg_datadir (), "qualified.txt", NULL);
62 listfp = fopen (listname, "r");
63 if (!listfp && errno != ENOENT)
65 err = gpg_error_from_syserror ();
66 log_error (_("can't open `%s': %s\n"), listname, gpg_strerror (err));
67 return err;
71 if (!listfp)
72 return gpg_error (GPG_ERR_EOF);
76 if (!fgets (line, DIM(line)-1, listfp) )
78 if (feof (listfp))
79 return gpg_error (GPG_ERR_EOF);
80 return gpg_error_from_syserror ();
83 if (!*line || line[strlen(line)-1] != '\n')
85 /* Eat until end of line. */
86 while ( (c=getc (listfp)) != EOF && c != '\n')
88 return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
89 : GPG_ERR_INCOMPLETE_LINE);
91 ++*lnr;
93 /* Allow for empty lines and spaces */
94 for (p=line; spacep (p); p++)
97 while (!*p || *p == '\n' || *p == '#');
99 for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
100 if ( p[i] != ':' )
101 key[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
102 key[j] = 0;
103 if (j != 40 || !(spacep (p+i) || p[i] == '\n'))
105 log_error (_("invalid formatted fingerprint in `%s', line %d\n"),
106 listname, *lnr);
107 return gpg_error (GPG_ERR_BAD_DATA);
109 assert (p[i]);
110 i++;
111 while (spacep (p+i))
112 i++;
113 if ( p[i] >= 'a' && p[i] <= 'z'
114 && p[i+1] >= 'a' && p[i+1] <= 'z'
115 && (spacep (p+i+2) || p[i+2] == '\n'))
117 country[0] = p[i];
118 country[1] = p[i+1];
119 country[2] = 0;
121 else
123 log_error (_("invalid country code in `%s', line %d\n"), listname, *lnr);
124 return gpg_error (GPG_ERR_BAD_DATA);
127 return 0;
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.
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 gpgsm_is_in_qualified_list (ctrl_t ctrl, ksba_cert_t cert, char *country)
148 gpg_error_t err;
149 char *fpr;
150 char key[41];
151 char mycountry[3];
152 int lnr = 0;
154 if (country)
155 *country = 0;
157 fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
158 if (!fpr)
159 return gpg_error (GPG_ERR_GENERAL);
161 if (listfp)
162 rewind (listfp);
163 while (!(err = read_list (key, mycountry, &lnr)))
165 if (!strcmp (key, fpr))
166 break;
168 if (gpg_err_code (err) == GPG_ERR_EOF)
169 err = gpg_error (GPG_ERR_NOT_FOUND);
171 if (!err && country)
172 strcpy (country, mycountry);
174 xfree (fpr);
175 return err;
179 /* We know that CERT is a qualified certificate. Ask the user for
180 consent to actually create a signature using this certificate.
181 Returns: 0 for yes, GPG_ERR_CANCEL for no or any otehr error
182 code. */
183 gpg_error_t
184 gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert)
186 gpg_error_t err;
187 char *name, *subject, *buffer, *p;
188 const char *s;
189 char *orig_codeset = NULL;
191 name = ksba_cert_get_subject (cert, 0);
192 if (!name)
193 return gpg_error (GPG_ERR_GENERAL);
194 subject = gpgsm_format_name2 (name, 0);
195 ksba_free (name); name = NULL;
197 orig_codeset = i18n_switchto_utf8 ();
199 if (asprintf (&name,
200 _("You are about to create a signature using your "
201 "certificate:\n"
202 "\"%s\"\n"
203 "This will create a qualified signature by law "
204 "equated to a handwritten signature.\n\n%s%s"
205 "Are you really sure that you want to do this?"),
206 subject? subject:"?",
207 opt.qualsig_approval?
209 _("Note, that this software is not officially approved "
210 "to create or verify such signatures.\n"),
211 opt.qualsig_approval? "":"\n"
212 ) < 0 )
213 err = gpg_error_from_syserror ();
214 else
215 err = 0;
217 i18n_switchback (orig_codeset);
218 xfree (orig_codeset);
219 xfree (subject);
221 if (err)
222 return err;
224 buffer = p = xtrymalloc (strlen (name) * 3 + 1);
225 if (!buffer)
227 err = gpg_error_from_syserror ();
228 free (name);
229 return err;
231 for (s=name; *s; s++)
233 if (*s < ' ' || *s == '+')
235 sprintf (p, "%%%02X", *(unsigned char *)s);
236 p += 3;
238 else if (*s == ' ')
239 *p++ = '+';
240 else
241 *p++ = *s;
243 *p = 0;
244 free (name);
247 err = gpgsm_agent_get_confirmation (ctrl, buffer);
249 xfree (buffer);
250 return err;
254 /* Popup a prompt to inform the user that the signature created is not
255 a qualified one. This is of course only done if we know that we
256 have been approved. */
257 gpg_error_t
258 gpgsm_not_qualified_warning (ctrl_t ctrl, ksba_cert_t cert)
260 gpg_error_t err;
261 char *name, *subject, *buffer, *p;
262 const char *s;
263 char *orig_codeset;
265 if (!opt.qualsig_approval)
266 return 0;
268 name = ksba_cert_get_subject (cert, 0);
269 if (!name)
270 return gpg_error (GPG_ERR_GENERAL);
271 subject = gpgsm_format_name2 (name, 0);
272 ksba_free (name); name = NULL;
274 orig_codeset = i18n_switchto_utf8 ();
276 if (asprintf (&name,
277 _("You are about to create a signature using your "
278 "certificate:\n"
279 "\"%s\"\n"
280 "Note, that this certificate will NOT create a "
281 "qualified signature!"),
282 subject? subject:"?") < 0 )
283 err = gpg_error_from_syserror ();
284 else
285 err = 0;
287 i18n_switchback (orig_codeset);
288 xfree (subject);
290 if (err)
291 return err;
293 buffer = p = xtrymalloc (strlen (name) * 3 + 1);
294 if (!buffer)
296 err = gpg_error_from_syserror ();
297 free (name);
298 return err;
300 for (s=name; *s; s++)
302 if (*s < ' ' || *s == '+')
304 sprintf (p, "%%%02X", *(unsigned char *)s);
305 p += 3;
307 else if (*s == ' ')
308 *p++ = '+';
309 else
310 *p++ = *s;
312 *p = 0;
313 free (name);
316 err = gpgsm_agent_get_confirmation (ctrl, buffer);
318 xfree (buffer);
319 return err;