Changed to GPLv3.
[gnupg.git] / sm / certlist.c
1 /* certlist.c - build list of certificates
2  *      Copyright (C) 2001, 2003, 2004, 2005 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 <errno.h>
25 #include <unistd.h> 
26 #include <time.h>
27 #include <assert.h>
28
29 #include "gpgsm.h"
30 #include <gcrypt.h>
31 #include <ksba.h>
32
33 #include "keydb.h"
34 #include "i18n.h"
35
36
37 static const char oid_kp_serverAuth[]     = "1.3.6.1.5.5.7.3.1";
38 static const char oid_kp_clientAuth[]     = "1.3.6.1.5.5.7.3.2";
39 static const char oid_kp_codeSigning[]    = "1.3.6.1.5.5.7.3.3";
40 static const char oid_kp_emailProtection[]= "1.3.6.1.5.5.7.3.4";
41 static const char oid_kp_timeStamping[]   = "1.3.6.1.5.5.7.3.8";
42 static const char oid_kp_ocspSigning[]    = "1.3.6.1.5.5.7.3.9";
43
44 /* Return 0 if the cert is usable for encryption.  A MODE of 0 checks
45    for signing a MODE of 1 checks for encryption, a MODE of 2 checks
46    for verification and a MODE of 3 for decryption (just for
47    debugging).  MODE 4 is for certificate signing, MODE for COSP
48    response signing. */
49 static int
50 cert_usage_p (ksba_cert_t cert, int mode)
51 {
52   gpg_error_t err;
53   unsigned int use;
54   char *extkeyusages;
55   int have_ocsp_signing = 0;
56
57   err = ksba_cert_get_ext_key_usages (cert, &extkeyusages);
58   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
59     err = 0; /* no policy given */
60   if (!err)
61     {
62       unsigned int extusemask = ~0; /* Allow all. */
63
64       if (extkeyusages)
65         {
66           char *p, *pend;
67           int any_critical = 0;
68
69           extusemask = 0;
70
71           p = extkeyusages;
72           while (p && (pend=strchr (p, ':')))
73             {
74               *pend++ = 0;
75               /* Only care about critical flagged usages. */
76               if ( *pend == 'C' )
77                 {
78                   any_critical = 1;
79                   if ( !strcmp (p, oid_kp_serverAuth))
80                     extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
81                                    | KSBA_KEYUSAGE_KEY_ENCIPHERMENT
82                                    | KSBA_KEYUSAGE_KEY_AGREEMENT);
83                   else if ( !strcmp (p, oid_kp_clientAuth))
84                     extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
85                                    | KSBA_KEYUSAGE_KEY_AGREEMENT);
86                   else if ( !strcmp (p, oid_kp_codeSigning))
87                     extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE);
88                   else if ( !strcmp (p, oid_kp_emailProtection))
89                     extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
90                                    | KSBA_KEYUSAGE_NON_REPUDIATION
91                                    | KSBA_KEYUSAGE_KEY_ENCIPHERMENT
92                                    | KSBA_KEYUSAGE_KEY_AGREEMENT);
93                   else if ( !strcmp (p, oid_kp_timeStamping))
94                     extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
95                                    | KSBA_KEYUSAGE_NON_REPUDIATION);
96                 }
97               
98               /* This is a hack to cope with OCSP.  Note that we do
99                  not yet fully comply with the requirements and that
100                  the entire CRL/OCSP checking thing should undergo a
101                  thorough review and probably redesign. */
102               if ( !strcmp (p, oid_kp_ocspSigning))
103                 have_ocsp_signing = 1;
104
105               if ((p = strchr (pend, '\n')))
106                 p++;
107             }
108           xfree (extkeyusages);
109           extkeyusages = NULL;
110           
111           if (!any_critical)
112             extusemask = ~0; /* Reset to the don't care mask. */
113         }
114
115
116       err = ksba_cert_get_key_usage (cert, &use);
117       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
118         {
119           err = 0;
120           if (opt.verbose && mode < 2)
121             log_info (_("no key usage specified - assuming all usages\n"));
122           use = ~0;
123         }
124
125       /* Apply extKeyUsage. */
126       use &= extusemask;
127
128     }
129   if (err)
130     { 
131       log_error (_("error getting key usage information: %s\n"),
132                  gpg_strerror (err));
133       xfree (extkeyusages);
134       return err;
135     } 
136
137   if (mode == 4)
138     {
139       if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN)))
140         return 0;
141       log_info (_("certificate should have not "
142                   "been used for certification\n"));
143       return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
144     }
145
146   if (mode == 5)
147     {
148       if (use != ~0 
149           && (have_ocsp_signing
150               || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN
151                          |KSBA_KEYUSAGE_CRL_SIGN))))
152         return 0;
153       log_info (_("certificate should have not "
154                   "been used for OCSP response signing\n"));
155       return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
156     }
157
158   if ((use & ((mode&1)?
159               (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT):
160               (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
161       )
162     return 0;
163
164   log_info (mode==3? _("certificate should have not been used for encryption\n"):
165             mode==2? _("certificate should have not been used for signing\n"):
166             mode==1? _("certificate is not usable for encryption\n"):
167                      _("certificate is not usable for signing\n"));
168   return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
169 }
170
171
172 /* Return 0 if the cert is usable for signing */
173 int
174 gpgsm_cert_use_sign_p (ksba_cert_t cert)
175 {
176   return cert_usage_p (cert, 0);
177 }
178
179
180 /* Return 0 if the cert is usable for encryption */
181 int
182 gpgsm_cert_use_encrypt_p (ksba_cert_t cert)
183 {
184   return cert_usage_p (cert, 1);
185 }
186
187 int
188 gpgsm_cert_use_verify_p (ksba_cert_t cert)
189 {
190   return cert_usage_p (cert, 2);
191 }
192
193 int
194 gpgsm_cert_use_decrypt_p (ksba_cert_t cert)
195 {
196   return cert_usage_p (cert, 3);
197 }
198
199 int
200 gpgsm_cert_use_cert_p (ksba_cert_t cert)
201 {
202   return cert_usage_p (cert, 4);
203 }
204
205 int
206 gpgsm_cert_use_ocsp_p (ksba_cert_t cert)
207 {
208   return cert_usage_p (cert, 5);
209 }
210
211
212 static int
213 same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert)
214 {
215   char *subject2 = ksba_cert_get_subject (cert, 0);
216   char *issuer2 = ksba_cert_get_subject (cert, 0);
217   int tmp;
218   
219   tmp = (subject && subject2
220          && !strcmp (subject, subject2)
221          && issuer && issuer2
222          && !strcmp (issuer, issuer2));
223   xfree (subject2);
224   xfree (issuer2);
225   return tmp;
226 }
227
228 /* Return true if CERT is already contained in CERTLIST. */
229 static int
230 is_cert_in_certlist (ksba_cert_t cert, certlist_t certlist)
231 {
232   const unsigned char *img_a, *img_b;
233   size_t len_a, len_b;
234
235   img_a = ksba_cert_get_image (cert, &len_a);
236   if (img_a)
237     {
238       for ( ; certlist; certlist = certlist->next)
239         {
240           img_b = ksba_cert_get_image (certlist->cert, &len_b);
241           if (img_b && len_a == len_b && !memcmp (img_a, img_b, len_a))
242             return 1; /* Already contained. */
243         }
244     }
245   return 0;
246 }
247
248
249 /* Add CERT to the list of certificates at CERTADDR but avoid
250    duplicates. */
251 int 
252 gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
253                             certlist_t *listaddr, int is_encrypt_to)
254 {
255   if (!is_cert_in_certlist (cert, *listaddr))
256     {
257       certlist_t cl = xtrycalloc (1, sizeof *cl);
258       if (!cl)
259         return out_of_core ();
260       cl->cert = cert;
261       ksba_cert_ref (cert);
262       cl->next = *listaddr;
263       cl->is_encrypt_to = is_encrypt_to;
264       *listaddr = cl;
265     }
266    return 0;
267 }
268
269 /* Add a certificate to a list of certificate and make sure that it is
270    a valid certificate.  With SECRET set to true a secret key must be
271    available for the certificate. IS_ENCRYPT_TO sets the corresponding
272    flag in the new create LISTADDR item.  */
273 int
274 gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
275                        certlist_t *listaddr, int is_encrypt_to)
276 {
277   int rc;
278   KEYDB_SEARCH_DESC desc;
279   KEYDB_HANDLE kh = NULL;
280   ksba_cert_t cert = NULL;
281
282   rc = keydb_classify_name (name, &desc);
283   if (!rc)
284     {
285       kh = keydb_new (0);
286       if (!kh)
287         rc = gpg_error (GPG_ERR_ENOMEM);
288       else
289         {
290           int wrong_usage = 0;
291           char *subject = NULL;
292           char *issuer = NULL;
293
294         get_next:
295           rc = keydb_search (kh, &desc, 1);
296           if (!rc)
297             rc = keydb_get_cert (kh, &cert);
298           if (!rc)
299             {
300               rc = secret? gpgsm_cert_use_sign_p (cert)
301                          : gpgsm_cert_use_encrypt_p (cert);
302               if (gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE)
303                 {
304                   /* There might be another certificate with the
305                      correct usage, so we try again */
306                   if (!wrong_usage)
307                     { /* save the first match */
308                       wrong_usage = rc;
309                       subject = ksba_cert_get_subject (cert, 0);
310                       issuer = ksba_cert_get_subject (cert, 0);
311                       ksba_cert_release (cert);
312                       cert = NULL;
313                       goto get_next;
314                     }
315                   else if (same_subject_issuer (subject, issuer, cert))
316                     {
317                       wrong_usage = rc;
318                       ksba_cert_release (cert);
319                       cert = NULL;
320                       goto get_next;
321                     }
322                   else
323                     wrong_usage = rc;
324
325                 }
326             }
327           /* We want the error code from the first match in this case. */
328           if (rc && wrong_usage)
329             rc = wrong_usage;
330           
331           if (!rc)
332             {
333             next_ambigious:
334               rc = keydb_search (kh, &desc, 1);
335               if (rc == -1)
336                 rc = 0;
337               else if (!rc)
338                 {
339                   ksba_cert_t cert2 = NULL;
340
341                   /* We have to ignore ambigious names as long as
342                      there only fault is a bad key usage */
343                   if (!keydb_get_cert (kh, &cert2))
344                     {
345                       int tmp = (same_subject_issuer (subject, issuer, cert2)
346                                  && ((gpg_err_code (
347                                       secret? gpgsm_cert_use_sign_p (cert2)
348                                             : gpgsm_cert_use_encrypt_p (cert2)
349                                       )
350                                      )  == GPG_ERR_WRONG_KEY_USAGE));
351                       ksba_cert_release (cert2);
352                       if (tmp)
353                         goto next_ambigious;
354                     }
355                   rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
356                 }
357             }
358           xfree (subject);
359           xfree (issuer);
360
361           if (!rc && !is_cert_in_certlist (cert, *listaddr))
362             {
363               if (!rc && secret) 
364                 {
365                   char *p;
366                   
367                   rc = gpg_error (GPG_ERR_NO_SECKEY);
368                   p = gpgsm_get_keygrip_hexstring (cert);
369                   if (p)
370                     {
371                       if (!gpgsm_agent_havekey (ctrl, p))
372                         rc = 0;
373                       xfree (p);
374                     }
375                 }
376               if (!rc)
377                 rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0);
378               if (!rc)
379                 {
380                   certlist_t cl = xtrycalloc (1, sizeof *cl);
381                   if (!cl)
382                     rc = out_of_core ();
383                   else 
384                     {
385                       cl->cert = cert; cert = NULL;
386                       cl->next = *listaddr;
387                       cl->is_encrypt_to = is_encrypt_to;
388                       *listaddr = cl;
389                     }
390                 }
391             }
392         }
393     }
394   
395   keydb_release (kh);
396   ksba_cert_release (cert);
397   return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
398 }
399
400 void
401 gpgsm_release_certlist (certlist_t list)
402 {
403   while (list)
404     {
405       certlist_t cl = list->next;
406       ksba_cert_release (list->cert);
407       xfree (list);
408       list = cl;
409     }
410 }
411
412 \f
413 /* Like gpgsm_add_to_certlist, but look only for one certificate.  No
414    chain validation is done. If KEYID is not NULL it is take as an
415    additional filter value which must match the
416    subjectKeyIdentifier. */
417 int
418 gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
419 {
420   int rc;
421   KEYDB_SEARCH_DESC desc;
422   KEYDB_HANDLE kh = NULL;
423
424   *r_cert = NULL;
425   rc = keydb_classify_name (name, &desc);
426   if (!rc)
427     {
428       kh = keydb_new (0);
429       if (!kh)
430         rc = gpg_error (GPG_ERR_ENOMEM);
431       else
432         {
433         nextone:
434           rc = keydb_search (kh, &desc, 1);
435           if (!rc)
436             {
437               rc = keydb_get_cert (kh, r_cert);
438               if (!rc && keyid)
439                 {
440                   ksba_sexp_t subj;
441                   
442                   rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj);
443                   if (!rc)
444                     {
445                       if (cmp_simple_canon_sexp (keyid, subj))
446                         {
447                           xfree (subj);
448                           goto nextone;
449                         }
450                       xfree (subj);
451                       /* Okay: Here we know that the certificate's
452                          subjectKeyIdentifier matches the requested
453                          one. */
454                     }
455                   else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
456                     goto nextone;
457                 }
458             }
459
460           /* If we don't have the KEYID filter we need to check for
461              ambigious search results.  Note, that it is somehwat
462              reasonable to assume that a specification of a KEYID
463              won't lead to ambiguous names. */
464           if (!rc && !keyid)
465             {
466               rc = keydb_search (kh, &desc, 1);
467               if (rc == -1)
468                 rc = 0;
469               else 
470                 {
471                   if (!rc)
472                     rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
473                   ksba_cert_release (*r_cert);
474                   *r_cert = NULL;
475                 }
476             }
477         }
478     }
479   
480   keydb_release (kh);
481   return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
482 }
483