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