1 /* certlist.c - build list of certificates
2 * Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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,
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";
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
52 cert_usage_p (ksba_cert_t cert, int mode)
57 int have_ocsp_signing = 0;
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 */
64 unsigned int extusemask = ~0; /* Allow all. */
74 while (p && (pend=strchr (p, ':')))
77 /* Only care about critical flagged usages. */
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);
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;
107 if ((p = strchr (pend, '\n')))
110 xfree (extkeyusages);
114 extusemask = ~0; /* Reset to the don't care mask. */
118 err = ksba_cert_get_key_usage (cert, &use);
119 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
122 if (opt.verbose && mode < 2)
123 log_info (_("no key usage specified - assuming all usages\n"));
127 /* Apply extKeyUsage. */
133 log_error (_("error getting key usage information: %s\n"),
135 xfree (extkeyusages);
141 if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN)))
143 log_info (_("certificate should have not "
144 "been used for certification\n"));
145 return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
151 && (have_ocsp_signing
152 || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN
153 |KSBA_KEYUSAGE_CRL_SIGN))))
155 log_info (_("certificate should have not "
156 "been used for OCSP response signing\n"));
157 return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
160 if ((use & ((mode&1)?
161 (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT):
162 (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
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);
174 /* Return 0 if the cert is usable for signing */
176 gpgsm_cert_use_sign_p (ksba_cert_t cert)
178 return cert_usage_p (cert, 0);
182 /* Return 0 if the cert is usable for encryption */
184 gpgsm_cert_use_encrypt_p (ksba_cert_t cert)
186 return cert_usage_p (cert, 1);
190 gpgsm_cert_use_verify_p (ksba_cert_t cert)
192 return cert_usage_p (cert, 2);
196 gpgsm_cert_use_decrypt_p (ksba_cert_t cert)
198 return cert_usage_p (cert, 3);
202 gpgsm_cert_use_cert_p (ksba_cert_t cert)
204 return cert_usage_p (cert, 4);
208 gpgsm_cert_use_ocsp_p (ksba_cert_t cert)
210 return cert_usage_p (cert, 5);
215 same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert)
217 char *subject2 = ksba_cert_get_subject (cert, 0);
218 char *issuer2 = ksba_cert_get_subject (cert, 0);
221 tmp = (subject && subject2
222 && !strcmp (subject, subject2)
224 && !strcmp (issuer, issuer2));
230 /* Return true if CERT is already contained in CERTLIST. */
232 is_cert_in_certlist (ksba_cert_t cert, certlist_t certlist)
234 const unsigned char *img_a, *img_b;
237 img_a = ksba_cert_get_image (cert, &len_a);
240 for ( ; certlist; certlist = certlist->next)
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. */
251 /* Add CERT to the list of certificates at CERTADDR but avoid
254 gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
255 certlist_t *listaddr, int is_encrypt_to)
257 if (!is_cert_in_certlist (cert, *listaddr))
259 certlist_t cl = xtrycalloc (1, sizeof *cl);
261 return OUT_OF_CORE (errno);
263 ksba_cert_ref (cert);
264 cl->next = *listaddr;
265 cl->is_encrypt_to = is_encrypt_to;
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. */
276 gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
277 CERTLIST *listaddr, int is_encrypt_to)
280 KEYDB_SEARCH_DESC desc;
281 KEYDB_HANDLE kh = NULL;
282 ksba_cert_t cert = NULL;
284 rc = keydb_classify_name (name, &desc);
289 rc = gpg_error (GPG_ERR_ENOMEM);
293 char *subject = NULL;
297 rc = keydb_search (kh, &desc, 1);
299 rc = keydb_get_cert (kh, &cert);
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)
306 /* There might be another certificate with the
307 correct usage, so we try again */
309 { /* save the first match */
311 subject = ksba_cert_get_subject (cert, 0);
312 issuer = ksba_cert_get_subject (cert, 0);
313 ksba_cert_release (cert);
317 else if (same_subject_issuer (subject, issuer, cert))
320 ksba_cert_release (cert);
329 /* We want the error code from the first match in this case. */
330 if (rc && wrong_usage)
336 rc = keydb_search (kh, &desc, 1);
341 ksba_cert_t cert2 = NULL;
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))
347 int tmp = (same_subject_issuer (subject, issuer, cert2)
349 secret? gpgsm_cert_use_sign_p (cert2)
350 : gpgsm_cert_use_encrypt_p (cert2)
352 ) == GPG_ERR_WRONG_KEY_USAGE));
353 ksba_cert_release (cert2);
357 rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
363 if (!rc && !is_cert_in_certlist (cert, *listaddr))
369 rc = gpg_error (GPG_ERR_NO_SECKEY);
370 p = gpgsm_get_keygrip_hexstring (cert);
373 if (!gpgsm_agent_havekey (ctrl, p))
379 rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0);
382 CERTLIST cl = xtrycalloc (1, sizeof *cl);
384 rc = OUT_OF_CORE (errno);
387 cl->cert = cert; cert = NULL;
388 cl->next = *listaddr;
389 cl->is_encrypt_to = is_encrypt_to;
398 ksba_cert_release (cert);
399 return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
403 gpgsm_release_certlist (CERTLIST list)
407 CERTLIST cl = list->next;
408 ksba_cert_release (list->cert);
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. */
420 gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
423 KEYDB_SEARCH_DESC desc;
424 KEYDB_HANDLE kh = NULL;
427 rc = keydb_classify_name (name, &desc);
432 rc = gpg_error (GPG_ERR_ENOMEM);
436 rc = keydb_search (kh, &desc, 1);
439 rc = keydb_get_cert (kh, r_cert);
444 rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj);
447 if (cmp_simple_canon_sexp (keyid, subj))
453 /* Okay: Here we know that the certificate's
454 subjectKeyIdentifier matches the requested
457 else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
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. */
468 rc = keydb_search (kh, &desc, 1);
474 rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
475 ksba_cert_release (*r_cert);
483 return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;