diff cinst/mozilla.c @ 1012:a80abef948fa

(issue86) Initialize NSS db with empty pin in case it needs it.
author Andre Heinecke <andre.heinecke@intevation.de>
date Tue, 02 Sep 2014 15:20:24 +0200
parents 1cd1bfe82fc2
children 78798d3af8f0
line wrap: on
line diff
--- a/cinst/mozilla.c	Tue Sep 02 14:43:48 2014 +0200
+++ b/cinst/mozilla.c	Tue Sep 02 15:20:24 2014 +0200
@@ -61,6 +61,7 @@
 #include <dirent.h>
 #include <nss.h>
 #include <pk11pub.h>
+#include <secerr.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -622,16 +623,39 @@
                                     (int)dercert->len);
   trust = (CERTCertTrust *)xmalloc(sizeof(CERTCertTrust));
   CERT_DecodeTrustString(trust, "C,C,C");
-  if ((PK11_ImportCert(pk11slot, cert, CK_INVALID_HANDLE,
-                       cert_name, PR_FALSE)
-       == SECSuccess) &&
-      (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, trust)
-       == SECSuccess))
+  if (PK11_ImportCert(pk11slot, cert, CK_INVALID_HANDLE,
+                       cert_name, PR_FALSE) == SECSuccess)
     {
-      log_certificate_der (pdir, dercert->data, dercert->len, true);
-      success = true;
+      if(CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, trust) == SECSuccess)
+        {
+          log_certificate_der (pdir, dercert->data, dercert->len, true);
+          success = true;
+        }
     }
-  else
+  /* This could have happened on either the import cert or
+     the cert change trust. If Import Cert fails with that
+     error the certificate has in fact been added but with
+     random trist bits. See NSS Bug 595861.
+     Reference code can be found in gnome evolution under
+     smime/lib/e-cert-db.c */
+  if(PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN)
+    {
+      if (PK11_NeedUserInit (pk11slot))
+        {
+          PK11_InitPin (pk11slot, "", "");
+        }
+      if (PK11_Authenticate (pk11slot, PR_TRUE, NULL) != SECSuccess)
+        {
+          DEBUGPRINTF("Failed to authenticate.\n");
+        }
+      else if(CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, trust) == SECSuccess)
+        {
+          log_certificate_der (pdir, dercert->data, dercert->len, true);
+          success = true;
+        }
+    }
+
+  if (!success)
     {
       DEBUGPRINTF("Failed to install certificate '%s' to '%s'!\n", cert_name, pdir);
       ERRORPRINTF("Error installing certificate err: %i\n", PORT_GetError());

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