Implemented the chain model for X.509 validation.
[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,
378                                            0, NULL, 0, NULL);
379               if (!rc)
380                 {
381                   certlist_t cl = xtrycalloc (1, sizeof *cl);
382                   if (!cl)
383                     rc = out_of_core ();
384                   else 
385                     {
386                       cl->cert = cert; cert = NULL;
387                       cl->next = *listaddr;
388                       cl->is_encrypt_to = is_encrypt_to;
389                       *listaddr = cl;
390                     }
391                 }
392             }
393         }
394     }
395   
396   keydb_release (kh);
397   ksba_cert_release (cert);
398   return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
399 }
400
401 void
402 gpgsm_release_certlist (certlist_t list)
403 {
404   while (list)
405     {
406       certlist_t cl = list->next;
407       ksba_cert_release (list->cert);
408       xfree (list);
409       list = cl;
410     }
411 }
412
413 \f
414 /* Like gpgsm_add_to_certlist, but look only for one certificate.  No
415    chain validation is done. If KEYID is not NULL it is take as an
416    additional filter value which must match the
417    subjectKeyIdentifier. */
418 int
419 gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
420 {
421   int rc;
422   KEYDB_SEARCH_DESC desc;
423   KEYDB_HANDLE kh = NULL;
424
425   *r_cert = NULL;
426   rc = keydb_classify_name (name, &desc);
427   if (!rc)
428     {
429       kh = keydb_new (0);
430       if (!kh)
431         rc = gpg_error (GPG_ERR_ENOMEM);
432       else
433         {
434         nextone:
435           rc = keydb_search (kh, &desc, 1);
436           if (!rc)
437             {
438               rc = keydb_get_cert (kh, r_cert);
439               if (!rc && keyid)
440                 {
441                   ksba_sexp_t subj;
442                   
443                   rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj);
444                   if (!rc)
445                     {
446                       if (cmp_simple_canon_sexp (keyid, subj))
447                         {
448                           xfree (subj);
449                           goto nextone;
450                         }
451                       xfree (subj);
452                       /* Okay: Here we know that the certificate's
453                          subjectKeyIdentifier matches the requested
454                          one. */
455                     }
456                   else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
457                     goto nextone;
458                 }
459             }
460
461           /* If we don't have the KEYID filter we need to check for
462              ambigious search results.  Note, that it is somehwat
463              reasonable to assume that a specification of a KEYID
464              won't lead to ambiguous names. */
465           if (!rc && !keyid)
466             {
467               rc = keydb_search (kh, &desc, 1);
468               if (rc == -1)
469                 rc = 0;
470               else 
471                 {
472                   if (!rc)
473                     rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
474                   ksba_cert_release (*r_cert);
475                   *r_cert = NULL;
476                 }
477             }
478         }
479     }
480   
481   keydb_release (kh);
482   return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
483 }
484