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