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