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