/* certlist.c - build list of certificates
- * Copyright (C) 2001, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2005, 2007,
+ * 2008, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <unistd.h>
+#include <unistd.h>
#include <time.h>
#include <assert.h>
extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE
| KSBA_KEYUSAGE_NON_REPUDIATION);
}
-
+
/* This is a hack to cope with OCSP. Note that we do
not yet fully comply with the requirements and that
the entire CRL/OCSP checking thing should undergo a
}
xfree (extkeyusages);
extkeyusages = NULL;
-
+
if (!any_critical)
extusemask = ~0; /* Reset to the don't care mask. */
}
}
if (err)
- {
+ {
log_error (_("error getting key usage information: %s\n"),
gpg_strerror (err));
xfree (extkeyusages);
return err;
- }
+ }
if (mode == 4)
{
if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN)))
return 0;
- log_info (_("certificate should have not "
+ log_info (_("certificate should not have "
"been used for certification\n"));
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
}
if (mode == 5)
{
- if (use != ~0
+ if (use != ~0
&& (have_ocsp_signing
|| (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN
|KSBA_KEYUSAGE_CRL_SIGN))))
return 0;
- log_info (_("certificate should have not "
+ log_info (_("certificate should not have "
"been used for OCSP response signing\n"));
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
}
)
return 0;
- log_info (mode==3? _("certificate should have not been used for encryption\n"):
- mode==2? _("certificate should have not been used for signing\n"):
+ log_info (mode==3? _("certificate should not have been used for encryption\n"):
+ mode==2? _("certificate should not have been used for signing\n"):
mode==1? _("certificate is not usable for encryption\n"):
_("certificate is not usable for signing\n"));
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
}
+/* Return true if CERT has the well known private key extension. */
+int
+gpgsm_cert_has_well_known_private_key (ksba_cert_t cert)
+{
+ int idx;
+ const char *oid;
+
+ for (idx=0; !ksba_cert_get_extension (cert, idx,
+ &oid, NULL, NULL, NULL);idx++)
+ if (!strcmp (oid, "1.3.6.1.4.1.11591.2.2.2") )
+ return 1; /* Yes. */
+ return 0; /* No. */
+}
+
+
static int
same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert)
{
char *subject2 = ksba_cert_get_subject (cert, 0);
- char *issuer2 = ksba_cert_get_subject (cert, 0);
+ char *issuer2 = ksba_cert_get_issuer (cert, 0);
int tmp;
-
+
tmp = (subject && subject2
&& !strcmp (subject, subject2)
&& issuer && issuer2
/* Add CERT to the list of certificates at CERTADDR but avoid
duplicates. */
-int
+int
gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
certlist_t *listaddr, int is_encrypt_to)
{
+ (void)ctrl;
+
if (!is_cert_in_certlist (cert, *listaddr))
{
certlist_t cl = xtrycalloc (1, sizeof *cl);
KEYDB_HANDLE kh = NULL;
ksba_cert_t cert = NULL;
- rc = keydb_classify_name (name, &desc);
+ rc = classify_user_id (name, &desc, 0);
if (!rc)
{
kh = keydb_new (0);
else
{
int wrong_usage = 0;
- char *subject = NULL;
- char *issuer = NULL;
+ char *first_subject = NULL;
+ char *first_issuer = NULL;
get_next:
rc = keydb_search (kh, &desc, 1);
rc = keydb_get_cert (kh, &cert);
if (!rc)
{
+ if (!first_subject)
+ {
+ /* Save the the subject and the issuer for key usage
+ and ambiguous name tests. */
+ first_subject = ksba_cert_get_subject (cert, 0);
+ first_issuer = ksba_cert_get_issuer (cert, 0);
+ }
rc = secret? gpgsm_cert_use_sign_p (cert)
: gpgsm_cert_use_encrypt_p (cert);
if (gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE)
if (!wrong_usage)
{ /* save the first match */
wrong_usage = rc;
- subject = ksba_cert_get_subject (cert, 0);
- issuer = ksba_cert_get_subject (cert, 0);
ksba_cert_release (cert);
cert = NULL;
goto get_next;
}
- else if (same_subject_issuer (subject, issuer, cert))
+ else if (same_subject_issuer (first_subject, first_issuer,
+ cert))
{
wrong_usage = rc;
ksba_cert_release (cert);
/* We want the error code from the first match in this case. */
if (rc && wrong_usage)
rc = wrong_usage;
-
+
if (!rc)
{
certlist_t dup_certs = NULL;
else if (!rc)
{
ksba_cert_t cert2 = NULL;
-
- /* If this is the first possible duplicate, add the original
+
+ /* If this is the first possible duplicate, add the original
certificate to our list of duplicates. */
if (!dup_certs)
gpgsm_add_cert_to_certlist (ctrl, cert, &dup_certs, 0);
keybox). */
if (!keydb_get_cert (kh, &cert2))
{
- int tmp = (same_subject_issuer (subject, issuer, cert2)
+ int tmp = (same_subject_issuer (first_subject,
+ first_issuer,
+ cert2)
&& ((gpg_err_code (
secret? gpgsm_cert_use_sign_p (cert2)
: gpgsm_cert_use_encrypt_p (cert2)
if (is_cert_in_certlist (cert2, dup_certs))
tmp = 1;
}
-
+
ksba_cert_release (cert2);
if (tmp)
goto next_ambigious;
}
gpgsm_release_certlist (dup_certs);
}
- xfree (subject);
- xfree (issuer);
+ xfree (first_subject);
+ xfree (first_issuer);
+ first_subject = NULL;
+ first_issuer = NULL;
if (!rc && !is_cert_in_certlist (cert, *listaddr))
{
- if (!rc && secret)
+ if (!rc && secret)
{
char *p;
-
+
rc = gpg_error (GPG_ERR_NO_SECKEY);
p = gpgsm_get_keygrip_hexstring (cert);
if (p)
certlist_t cl = xtrycalloc (1, sizeof *cl);
if (!cl)
rc = out_of_core ();
- else
+ else
{
cl->cert = cert; cert = NULL;
cl->next = *listaddr;
}
}
}
-
+
keydb_release (kh);
ksba_cert_release (cert);
return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
}
+
void
gpgsm_release_certlist (certlist_t list)
{
KEYDB_HANDLE kh = NULL;
*r_cert = NULL;
- rc = keydb_classify_name (name, &desc);
+ rc = classify_user_id (name, &desc, 0);
if (!rc)
{
kh = keydb_new (0);
if (!rc && keyid)
{
ksba_sexp_t subj;
-
+
rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj);
if (!rc)
{
rc = keydb_search (kh, &desc, 1);
if (rc == -1)
rc = 0;
- else
+ else
{
if (!rc)
{
}
}
}
-
+
keydb_release (kh);
return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
}
-