Add gpgsm server command GETINFO agent-check.
[gnupg.git] / sm / certlist.c
index 3afdbc3..2b717ef 100644 (file)
@@ -1,5 +1,6 @@
 /* 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 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -213,7 +214,7 @@ 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
@@ -307,8 +308,8 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
       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);
@@ -316,6 +317,13 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
             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)
@@ -325,13 +333,12 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                   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);
@@ -359,7 +366,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                 {
                   ksba_cert_t cert2 = NULL;
                   
-                  /* If this is the first possible duplicate, add thye orginal 
+                  /* 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);
@@ -367,7 +374,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                   /* We have to ignore ambigious names as long as
                      there only fault is a bad key usage.  This is
                      required to support encryption and signing
-                     certifciates of the same subject.
+                     certificates of the same subject.
 
                      Further we ignore them if they are due to an
                      identical certificate (which may happen if a
@@ -375,7 +382,9 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                      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)
@@ -398,8 +407,10 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                 }
               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))
             {
@@ -441,6 +452,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
   return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc;
 }
 
+
 void
 gpgsm_release_certlist (certlist_t list)
 {
@@ -455,7 +467,7 @@ gpgsm_release_certlist (certlist_t list)
 
 \f
 /* Like gpgsm_add_to_certlist, but look only for one certificate.  No
-   chain validation is done. If KEYID is not NULL it is take as an
+   chain validation is done.  If KEYID is not NULL it is taken as an
    additional filter value which must match the
    subjectKeyIdentifier. */
 int