diff cinst/windowsstore.c @ 215:292e2cb60ef0

Add removal of certificates
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 26 Mar 2014 17:18:00 +0100
parents ee37c085b9f7
children 83a015f2e078
line wrap: on
line diff
--- a/cinst/windowsstore.c	Wed Mar 26 17:17:19 2014 +0100
+++ b/cinst/windowsstore.c	Wed Mar 26 17:18:00 2014 +0100
@@ -32,12 +32,143 @@
   return bufPtr;
 }
 
-int write_stores_win (char **to_install, char **to_remove, bool user_store)
+static void
+do_remove(HCERTSTORE hStore, char **to_remove)
 {
-  int i = 0;
-  int ret = -1;
+  PCCERT_CONTEXT pCert = NULL;
+  unsigned int i = 0;
+
+  if (!to_remove)
+    {
+      return;
+    }
+
+  for (i=0; to_remove[i]; i++)
+    {
+      char *asn1_data = NULL;
+      size_t asn1_size = 0;
+      int ret = -1;
+      PCCERT_CONTEXT pc_to_remove = NULL;
+
+      ret = str_base64_decode (&asn1_data, &asn1_size, to_remove[i],
+                               strnlen(to_remove[i], MAX_LINE_LENGTH));
+      /* Decoding / parsing errors in here should not happen at all.
+         The only errors which are not a bug would be out of memory or
+         if the signed certificate list contained an invalid certificate. */
+      if (ret != 0)
+        {
+          printf ("Error base64 certificate.\n");
+          continue;
+        }
+
+      pc_to_remove = CertCreateContext (CERT_STORE_CERTIFICATE_CONTEXT,
+                                        X509_ASN_ENCODING,
+                                        (const PBYTE) asn1_data,
+                                        (DWORD) asn1_size,
+                                        0,
+                                        NULL);
+      free (asn1_data); /* Windows has a copy */
+      if (pc_to_remove == NULL)
+        {
+          LPWSTR error = getLastErrorMsg();
+          if (error)
+            {
+              printf ("Failed to add certificate: %S \n", error);
+              LocalFree (error);
+            }
+          continue;
+        }
+
+      pCert = CertFindCertificateInStore (hStore,
+                                          X509_ASN_ENCODING,
+                                          0,
+                                          CERT_FIND_EXISTING,
+                                          pc_to_remove,
+                                          NULL);
+
+      CertFreeCertificateContext (pc_to_remove);
+
+      if (pCert == NULL)
+        {
+          printf ("Did not find certificate\n");
+          continue;
+        }
+
+      if (!CertDeleteCertificateFromStore (pCert))
+        {
+          /* From MSDN:
+             The CertDeleteCertificateFromStore function always frees
+             pCertContext by calling the CertFreeCertificateContext
+             function, even if an error is encountered. */
+          LPWSTR error = getLastErrorMsg();
+          printf ("Error deleting certificate. %S", error);
+          LocalFree (error);
+          continue;
+        }
+    }
+  return;
+}
+
+static void
+do_install(HCERTSTORE hStore, char **to_install)
+{
+  int i = 0,
+      ret = -1;
+
+  if (!to_install)
+    {
+      return;
+    }
+
+  for (i=0; to_install[i]; i++)
+    {
+      size_t cert_len = strnlen (to_install[i], MAX_LINE_LENGTH),
+             buf_size = 0;
+      char *buf = NULL;
+
+      ret = str_base64_decode (&buf, &buf_size, to_install[i], cert_len);
+
+      if (ret != 0)
+        {
+          printf ("decoding certificate failed\n");
+          return;
+        }
+
+      printf ("Adding cert %s\n", to_install[i]);
+
+      ret = CertAddEncodedCertificateToStore (hStore,
+                                              X509_ASN_ENCODING,
+                                              (PBYTE) buf,
+                                              buf_size,
+                                              CERT_STORE_ADD_ALWAYS,
+                                              NULL);
+
+      if (!ret)
+        {
+          LPWSTR error = getLastErrorMsg();
+          if (error)
+            {
+              printf ("Failed to add certificate: %S \n", error);
+              LocalFree (error);
+            }
+        }
+      i++;
+      free (buf);
+    }
+  return;
+}
+
+int
+write_stores_win (char **to_install, char **to_remove, bool user_store)
+{
   HCERTSTORE hStore = NULL;
 
+  if (!to_install && !to_remove)
+    {
+      /* Nothing to do */
+      return 0;
+    }
+
   if (user_store)
     {
       hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0,
@@ -54,43 +185,10 @@
       return ERR_STORE_ACCESS_DENIED;
     }
 
-  for (i=0; to_install[i]; i++)
-    {
-      size_t cert_len = strnlen (to_install[i], MAX_LINE_LENGTH),
-             buf_size = 0;
-      char *buf = NULL;
-
-      ret = str_base64_decode (&buf, &buf_size, to_install[i], cert_len);
-
-      if (ret != 0)
-        {
-          return ERR_INVALID_INSTRUCTIONS;
-        }
+  /* Do the actual work */
+  do_install (hStore, to_install);
 
-      ret = CertAddEncodedCertificateToStore (hStore,
-                                              X509_ASN_ENCODING,
-                                              (PBYTE) buf,
-                                              buf_size,
-                                              CERT_STORE_ADD_ALWAYS,
-                                              NULL);
-
-      if (ret == 0)
-        {
-          LPWSTR error = getLastErrorMsg();
-          if (error)
-            {
-              printf ("Failed to add certificate: %S \n", error);
-              LocalFree (error);
-            }
-        }
-      i++;
-      free (buf);
-    }
-
-  for (i=0; to_remove[i]; i++)
-    {
-      // TODO
-    }
+  do_remove (hStore, to_remove);
 
   if (hStore)
     {

http://wald.intevation.org/projects/trustbridge/