diff --git a/truststore_nss.go b/truststore_nss.go
index d288eb837ad9fac0d6fbda70bd57f5def80602d7..b77133acebd117a875b111b87b123b50c130b08a 100644
--- a/truststore_nss.go
+++ b/truststore_nss.go
@@ -1,12 +1,11 @@
-// +build ignore
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
+// Copyright (c) 2018 The truststore Authors. All rights reserved.
+// Copyright (c) 2018 The mkcert Authors. All rights reserved.
 
 package truststore
 
 import (
-	"log"
+	"crypto/x509"
+	"fmt"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -15,52 +14,72 @@ import (
 )
 
 var (
-	hasNSS       bool
-	hasCertutil  bool
 	certutilPath string
 	nssDB        = filepath.Join(os.Getenv("HOME"), ".pki/nssdb")
 )
 
-func init() {
+func hasNSS() bool {
 	for _, path := range []string{
 		"/usr/bin/firefox", nssDB, "/Applications/Firefox.app",
 		"/Applications/Firefox Developer Edition.app",
 		"/Applications/Firefox Nightly.app",
 		"C:\\Program Files\\Mozilla Firefox",
 	} {
-		_, err := os.Stat(path)
-		hasNSS = hasNSS || err == nil
+		if _, err := os.Stat(path); err == nil {
+			return true
+		}
+	}
+	// Try with user defined path
+	if path := os.Getenv("TRUSTSTORE_NSS_LOCATION"); path != "" {
+		if _, err := os.Stat(path); err == nil {
+			fmt.Println()
+			return true
+		} else {
+			println(err.Error())
+		}
 	}
 
+	debug("%s not found. Try to define the environment variable TRUSTSTORE_NSS_LOCATION", NSSBrowsers)
+	return false
+}
+
+func hasCertUtil() bool {
+	var err error
 	switch runtime.GOOS {
 	case "darwin":
-		var err error
 		certutilPath, err = exec.LookPath("certutil")
 		if err != nil {
-			var out []byte
-			out, err = exec.Command("brew", "--prefix", "nss").Output()
-			if err != nil {
-				return
+			out, err1 := exec.Command("brew", "--prefix", "nss").Output()
+			if err1 != nil {
+				return false
 			}
 			certutilPath = filepath.Join(strings.TrimSpace(string(out)), "bin", "certutil")
 			_, err = os.Stat(certutilPath)
 		}
-		hasCertutil = err == nil
-
+		return err == nil
 	case "linux":
-		var err error
 		certutilPath, err = exec.LookPath("certutil")
-		hasCertutil = err == nil
+		return err == nil
+	default:
+		return false
 	}
 }
 
-func (m *mkcert) checkNSS() bool {
-	if !hasCertutil {
+func checkNSS(cert *x509.Certificate) bool {
+	if !hasCertUtil() {
+		if CertutilInstallHelp == "" {
+			debug("Note: %s support is not available on your platform. ℹ️", NSSBrowsers)
+		} else {
+			debug(`Warning: "certutil" is not available, so the certificate can't be automatically installed in %s!`, NSSBrowsers)
+			debug(`Install "certutil" with "%s" and try again`, CertutilInstallHelp)
+		}
 		return false
 	}
+
+	// Check if the certificate is already installed
 	success := true
-	if m.forEachNSSProfile(func(profile string) {
-		err := exec.Command(certutilPath, "-V", "-d", profile, "-u", "L", "-n", m.caUniqueName()).Run()
+	if forEachNSSProfile(func(profile string) {
+		err := exec.Command(certutilPath, "-V", "-d", profile, "-u", "L", "-n", uniqueName(cert)).Run()
 		if err != nil {
 			success = false
 		}
@@ -70,36 +89,45 @@ func (m *mkcert) checkNSS() bool {
 	return success
 }
 
-func (m *mkcert) installNSS() bool {
-	if m.forEachNSSProfile(func(profile string) {
-		cmd := exec.Command(certutilPath, "-A", "-d", profile, "-t", "C,,", "-n", m.caUniqueName(), "-i", filepath.Join(m.CAROOT, rootName))
+func installNSS(filename string, cert *x509.Certificate) error {
+	// install certificate in all profiles
+	if forEachNSSProfile(func(profile string) {
+		cmd := exec.Command(certutilPath, "-A", "-d", profile, "-t", "C,,", "-n", uniqueName(cert), "-i", filename)
 		out, err := cmd.CombinedOutput()
-		fatalIfCmdErr(err, "certutil -A", out)
+		if err != nil {
+			debug("failed to execute \"certutil -A\": %s\n\n%s", err, out)
+		}
 	}) == 0 {
-		log.Printf("ERROR: no %s security databases found", NSSBrowsers)
-		return false
+		return fmt.Errorf("not %s security databases found", NSSBrowsers)
 	}
-	if !m.checkNSS() {
-		log.Printf("Installing in %s failed. Please report the issue with details about your environment at https://github.com/FiloSottile/mkcert/issues/new 👎", NSSBrowsers)
-		log.Printf("Note that if you never started %s, you need to do that at least once.", NSSBrowsers)
-		return false
+	// check for the cert in all profiles
+	if !checkNSS(cert) {
+		return fmt.Errorf("certificate cannot be installed in %s", NSSBrowsers)
 	}
-	return true
+	debug("certificate installed properly in %s", NSSBrowsers)
+	return nil
 }
 
-func (m *mkcert) uninstallNSS() {
-	m.forEachNSSProfile(func(profile string) {
-		err := exec.Command(certutilPath, "-V", "-d", profile, "-u", "L", "-n", m.caUniqueName()).Run()
+func uninstallNSS(filname string, cert *x509.Certificate) (err error) {
+	forEachNSSProfile(func(profile string) {
 		if err != nil {
 			return
 		}
-		cmd := exec.Command(certutilPath, "-D", "-d", profile, "-n", m.caUniqueName())
-		out, err := cmd.CombinedOutput()
-		fatalIfCmdErr(err, "certutil -D", out)
+		// skip if not found
+		if err := exec.Command(certutilPath, "-V", "-d", profile, "-u", "L", "-n", uniqueName(cert)).Run(); err != nil {
+			return
+		}
+		// delete certificate
+		cmd := exec.Command(certutilPath, "-D", "-d", profile, "-n", uniqueName(cert))
+		out, err1 := cmd.CombinedOutput()
+		if err1 != nil {
+			err = cmdError(err1, "certutil -D", out)
+		}
 	})
+	return
 }
 
-func (m *mkcert) forEachNSSProfile(f func(profile string)) (found int) {
+func forEachNSSProfile(f func(profile string)) (found int) {
 	profiles, _ := filepath.Glob(FirefoxProfile)
 	if _, err := os.Stat(nssDB); err == nil {
 		profiles = append(profiles, nssDB)