shill: Further deprecate CaCertNSS

Chrome has been updated to no longer set the CaCertNSS property
for OpenVPN, L2TP/IPSec and 802.1x connections.  It also has code
to migrate such properties over to the equivalent CaCertPEM
property.  This CL rips out the underpinnings in shill that used
to convert NSS properties by reading the user NSS database.  It
still supports the various NSS service properties for read (to
allow Chrome to detect and migrate away from the NSS property)
and write (so Chrome can clear the vestigial property) in all the
places where that was previously supported.

CQ-DEPEND=CL:205152
BUG=chromium:385401
TEST=Unit tests

Change-Id: Id3df385148acb8e9c4240bbaa980e4118aa6b088
Reviewed-on: https://chromium-review.googlesource.com/204763
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/doc/service-api.txt b/doc/service-api.txt
index 04ba1b2..7ec2595 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -650,21 +650,19 @@
 
 			(VPN services of type OpenVPN only) Specify the
 			filename of the certificate to be used to verify the
-			OpenVPN server.  Only one of "OpenVPN.CACert",
-			"OpenVPN.CACertNSS" or "OpenVPN.CACertPEM" can be
-			specified.  The current value of this property
-			is readable in the "Provider" property of this service.
+			OpenVPN server.  Only one of "OpenVPN.CACert" or
+			"OpenVPN.CACertPEM" can be specified.  The current
+			value of this property is readable in the "Provider"
+			property of this service.
 
 		string OpenVPN.CACertNSS [writeonly]
 
 			(VPN services of type OpenVPN only) [Deprecated]
-			Specify the NSS nickname for the certificate to be used
-			to verify the OpenVPN server.  This certificate will
-			be retrieved from currently logged in user's NSS
-			database.  Only one of "OpenVPN.CACert",
-			"OpenVPN.CACertNSS" or "OpenVPN.CACertPEM" can be
-			specified.  The current value of this property
-			is readable in the "Provider" property of this service.
+			This value is no longer honored in shill, but any
+			value stored here is persisted so that callers can
+			migrate this to the correct value of OpenVPN.CACertPEM.
+			The current value of this property is readable in the
+			"Provider" property of this service.
 
 		array{string} OpenVPN.CACertPEM [writeonly]
 
@@ -676,10 +674,9 @@
 			the base64 counterpart of the DER contents, optionally
 			surrounded by a "-----BEGIN CERTIFICATE-----" and
 			"-----END CERTIFICATE-----" line.  Only one of
-			"OpenVPN.CACert", "OpenVPN.CACertNSS" or
-			"OpenVPN.CACertPEM" can be specified.  The current
-			value of this property is readable in the "Provider"
-			property of this service.
+			"OpenVPN.CACert" or "OpenVPN.CACertPEM" can be
+			specified.  The current value of this property is
+			readable in the "Provider" property of this service.
 
 		string OpenVPN.Cert [writeonly]
 
diff --git a/eap_credentials.cc b/eap_credentials.cc
index e02a9e3..4e0f4c9 100644
--- a/eap_credentials.cc
+++ b/eap_credentials.cc
@@ -15,7 +15,6 @@
 #include "shill/logging.h"
 #include "shill/key_value_store.h"
 #include "shill/metrics.h"
-#include "shill/nss.h"
 #include "shill/property_accessor.h"
 #include "shill/property_store.h"
 #include "shill/service.h"
@@ -60,8 +59,6 @@
 // static
 void EapCredentials::PopulateSupplicantProperties(
     CertificateFile *certificate_file,
-    NSS *nss,
-    const vector<char> nss_identifier,
     map<string, DBus::Variant> *params) const {
   string ca_cert = ca_cert_;
   if (!ca_cert_pem_.empty()) {
@@ -72,13 +69,6 @@
     } else {
       ca_cert = certfile.value();
     }
-  } else if (!ca_cert_nss_.empty()) {
-    FilePath certfile = nss->GetDERCertfile(ca_cert_nss_, nss_identifier);
-    if (certfile.empty()) {
-      LOG(ERROR) << "Unable to extract DER certificate: " << ca_cert_nss_;
-    } else {
-      ca_cert = certfile.value();
-    }
   }
 
 
diff --git a/eap_credentials.h b/eap_credentials.h
index 3193968..dd38a14 100644
--- a/eap_credentials.h
+++ b/eap_credentials.h
@@ -20,7 +20,6 @@
 class Error;
 class KeyValueStore;
 class Metrics;
-class NSS;
 class PropertyStore;
 class StoreInterface;
 
@@ -75,11 +74,9 @@
 
   // Populate the wpa_supplicant DBus parameter map |params| with the
   // credentials in |this|.  To do so, this function may use |certificate_file|
-  // or |nss| to export CA certificates to be passed to wpa_supplicant.
+  // to export CA certificates to be passed to wpa_supplicant.
   virtual void PopulateSupplicantProperties(
       CertificateFile *certificate_file,
-      NSS *nss,
-      const std::vector<char> nss_identifier,
       std::map<std::string, DBus::Variant> *params) const;
 
   // Populate the WiMax connection parameters |params| with the
diff --git a/eap_credentials_unittest.cc b/eap_credentials_unittest.cc
index 2510250..e544431 100644
--- a/eap_credentials_unittest.cc
+++ b/eap_credentials_unittest.cc
@@ -13,7 +13,6 @@
 #include "shill/mock_event_dispatcher.h"
 #include "shill/mock_log.h"
 #include "shill/mock_metrics.h"
-#include "shill/mock_nss.h"
 #include "shill/mock_property_store.h"
 #include "shill/mock_store.h"
 #include "shill/technology.h"
@@ -40,8 +39,7 @@
 
  protected:
   void PopulateSupplicantProperties() {
-    eap_.PopulateSupplicantProperties(&certificate_file_, &nss_,
-                                      nss_identifier_, &params_);
+    eap_.PopulateSupplicantProperties(&certificate_file_, &params_);
   }
 
   void SetAnonymousIdentity(const string &anonymous_identity) {
@@ -122,8 +120,6 @@
 
   EapCredentials eap_;
   MockCertificateFile certificate_file_;
-  MockNSS nss_;
-  vector<char> nss_identifier_;
   map<string, ::DBus::Variant> params_;
 };
 
@@ -385,22 +381,6 @@
   EXPECT_TRUE(ContainsKey(params_, WPASupplicant::kNetworkPropertyEapCaCertId));
 }
 
-TEST_F(EapCredentialsTest, PopulateSupplicantPropertiesNSS) {
-  const string kNSSNickname("nss_nickname");
-  SetCACertNSS(kNSSNickname);
-  const string kNSSCertfile("/tmp/nss-cert");
-  FilePath nss_cert(kNSSCertfile);
-  nss_identifier_ = vector<char>(1, 'a');
-  EXPECT_CALL(nss_, GetDERCertfile(kNSSNickname, nss_identifier_))
-      .WillOnce(Return(nss_cert));
-  PopulateSupplicantProperties();
-  EXPECT_TRUE(ContainsKey(params_, WPASupplicant::kNetworkPropertyEapCaCert));
-  if (ContainsKey(params_, WPASupplicant::kNetworkPropertyEapCaCert)) {
-    EXPECT_EQ(kNSSCertfile, params_[WPASupplicant::kNetworkPropertyEapCaCert]
-              .reader().get_string());
-  }
-}
-
 TEST_F(EapCredentialsTest, PopulateSupplicantPropertiesPEM) {
   const vector<string> kPemCert{ "-pem-certificate-here-" };
   SetCACertPEM(kPemCert);
diff --git a/ethernet.cc b/ethernet.cc
index 106b54e..ac6ce29 100644
--- a/ethernet.cc
+++ b/ethernet.cc
@@ -30,7 +30,6 @@
 #include "shill/event_dispatcher.h"
 #include "shill/logging.h"
 #include "shill/manager.h"
-#include "shill/nss.h"
 #include "shill/profile.h"
 #include "shill/proxy_factory.h"
 #include "shill/rtnl_handler.h"
@@ -63,7 +62,6 @@
       is_eap_authenticated_(false),
       is_eap_detected_(false),
       eap_listener_(new EapListener(dispatcher, interface_index)),
-      nss_(NSS::GetInstance()),
       proxy_factory_(ProxyFactory::GetInstance()),
       sockets_(new Sockets()),
       weak_ptr_factory_(this) {
@@ -262,9 +260,8 @@
 
 bool Ethernet::StartEapAuthentication() {
   map<string, DBus::Variant> params;
-  vector<char> nss_identifier(link_name().begin(), link_name().end());
   GetEapService()->eap()->PopulateSupplicantProperties(
-      &certificate_file_, nss_, nss_identifier, &params);
+      &certificate_file_, &params);
   params[WPASupplicant::kNetworkPropertyEapKeyManagement].writer().
       append_string(WPASupplicant::kKeyManagementIeee8021X);
   params[WPASupplicant::kNetworkPropertyEapolFlags].writer().
diff --git a/ethernet.h b/ethernet.h
index 0052625..ecb5d93 100644
--- a/ethernet.h
+++ b/ethernet.h
@@ -24,7 +24,6 @@
 class CertificateFile;
 class EapListener;
 class EthernetEapProvider;
-class NSS;
 class ProxyFactory;
 class Sockets;
 class SupplicantEAPStateHandler;
@@ -120,9 +119,8 @@
   std::string supplicant_interface_path_;
   std::string supplicant_network_path_;
 
-  // NSS and certificate file instances are needed to generate public key
-  // data for remote authentication.
-  NSS *nss_;
+  // Certificate file instance to generate public key data for remote
+  // authentication.
   CertificateFile certificate_file_;
 
   // Make sure TryEapAuthenticationTask is only queued for execution once
diff --git a/ethernet_unittest.cc b/ethernet_unittest.cc
index 1091fb7..70c9a7a 100644
--- a/ethernet_unittest.cc
+++ b/ethernet_unittest.cc
@@ -426,7 +426,7 @@
   MockEapCredentials mock_eap_credentials;
   EXPECT_CALL(*mock_eap_service_, eap())
       .WillOnce(Return(&mock_eap_credentials));
-  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _, _, _));
+  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
   EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
   EXPECT_CALL(*interface_proxy, AddNetwork(_))
       .WillOnce(Throw(DBus::Error(
@@ -444,7 +444,7 @@
   EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
   EXPECT_CALL(*mock_eap_service_, eap())
       .WillOnce(Return(&mock_eap_credentials));
-  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _, _, _));
+  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
   const char kFirstNetworkPath[] = "/network/first-path";
   EXPECT_CALL(*interface_proxy, AddNetwork(_))
       .WillOnce(Return(kFirstNetworkPath));
@@ -461,7 +461,7 @@
   EXPECT_CALL(*interface_proxy, RemoveNetwork(StrEq(kFirstNetworkPath)));
   EXPECT_CALL(*mock_eap_service_, eap())
       .WillOnce(Return(&mock_eap_credentials));
-  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _, _, _));
+  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
   const char kSecondNetworkPath[] = "/network/second-path";
   EXPECT_CALL(*interface_proxy, AddNetwork(_))
       .WillOnce(Return(kSecondNetworkPath));
diff --git a/l2tp_ipsec_driver.cc b/l2tp_ipsec_driver.cc
index c203a9e..9a29bab 100644
--- a/l2tp_ipsec_driver.cc
+++ b/l2tp_ipsec_driver.cc
@@ -35,7 +35,6 @@
 #include "shill/external_task.h"
 #include "shill/logging.h"
 #include "shill/manager.h"
-#include "shill/nss.h"
 #include "shill/ppp_device.h"
 #include "shill/ppp_device_factory.h"
 #include "shill/vpn_service.h"
@@ -103,7 +102,6 @@
       metrics_(metrics),
       device_info_(device_info),
       glib_(glib),
-      nss_(NSS::GetInstance()),
       ppp_device_factory_(PPPDeviceFactory::GetInstance()),
       certificate_file_(new CertificateFile()),
       weak_ptr_factory_(this) {}
@@ -236,11 +234,8 @@
   // Disable pppd from configuring IP addresses, routes, DNS.
   options->push_back("--nosystemconfig");
 
-  // Accept a PEM CA certificate or an NSS certificate, but not both.
-  // Prefer PEM to NSS.
-  if (!InitPEMOptions(options)) {
-    InitNSSOptions(options);
-  }
+  // Accept a PEM CA certificate.
+  InitPEMOptions(options);
 
   AppendValueOption(kL2tpIpsecClientCertIdProperty,
                     "--client_cert_id", options);
@@ -287,22 +282,6 @@
   return true;
 }
 
-void L2TPIPSecDriver::InitNSSOptions(vector<string> *options) {
-  string ca_cert =
-      args()->LookupString(kL2tpIpsecCaCertNssProperty, "");
-  if (!ca_cert.empty()) {
-    const string &vpnhost = args()->GetString(kProviderHostProperty);
-    vector<char> id(vpnhost.begin(), vpnhost.end());
-    FilePath certfile = nss_->GetDERCertfile(ca_cert, id);
-    if (certfile.empty()) {
-      LOG(ERROR) << "Unable to extract certificate: " << ca_cert;
-    } else {
-      options->push_back("--server_ca_file");
-      options->push_back(certfile.value());
-    }
-  }
-}
-
 bool L2TPIPSecDriver::InitPEMOptions(vector<string> *options) {
   vector<string> ca_certs;
   if (args()->ContainsStrings(kL2tpIpsecCaCertPemProperty)) {
@@ -494,13 +473,6 @@
   // We output an enum for each of the authentication types specified,
   // even if more than one is set at the same time.
   bool has_remote_authentication = false;
-  if (args()->LookupString(kL2tpIpsecCaCertNssProperty, "") != "") {
-    metrics_->SendEnumToUMA(
-        Metrics::kMetricVpnRemoteAuthenticationType,
-        Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecCertificate,
-        Metrics::kMetricVpnRemoteAuthenticationTypeMax);
-    has_remote_authentication = true;
-  }
   if (args()->LookupString(kL2tpIpsecPskProperty, "") != "") {
     metrics_->SendEnumToUMA(
         Metrics::kMetricVpnRemoteAuthenticationType,
diff --git a/l2tp_ipsec_driver.h b/l2tp_ipsec_driver.h
index 7dc706b..2e9d7d2 100644
--- a/l2tp_ipsec_driver.h
+++ b/l2tp_ipsec_driver.h
@@ -28,7 +28,6 @@
 class ExternalTask;
 class GLib;
 class Metrics;
-class NSS;
 class PPPDeviceFactory;
 
 class L2TPIPSecDriver : public VPNDriver,
@@ -62,7 +61,6 @@
   FRIEND_TEST(L2TPIPSecDriverTest, Disconnect);
   FRIEND_TEST(L2TPIPSecDriverTest, GetLogin);
   FRIEND_TEST(L2TPIPSecDriverTest, InitEnvironment);
-  FRIEND_TEST(L2TPIPSecDriverTest, InitNSSOptions);
   FRIEND_TEST(L2TPIPSecDriverTest, InitOptions);
   FRIEND_TEST(L2TPIPSecDriverTest, InitOptionsNoHost);
   FRIEND_TEST(L2TPIPSecDriverTest, InitPEMOptions);
@@ -83,7 +81,6 @@
 
   bool InitOptions(std::vector<std::string> *options, Error *error);
   bool InitPSKOptions(std::vector<std::string> *options, Error *error);
-  void InitNSSOptions(std::vector<std::string> *options);
   bool InitPEMOptions(std::vector<std::string> *options);
   bool InitXauthOptions(std::vector<std::string> *options, Error *error);
 
@@ -139,7 +136,6 @@
   Metrics *metrics_;
   DeviceInfo *device_info_;
   GLib *glib_;
-  NSS *nss_;
   PPPDeviceFactory *ppp_device_factory_;
 
   VPNServiceRefPtr service_;
diff --git a/l2tp_ipsec_driver_unittest.cc b/l2tp_ipsec_driver_unittest.cc
index 6bf52cd..3662510 100644
--- a/l2tp_ipsec_driver_unittest.cc
+++ b/l2tp_ipsec_driver_unittest.cc
@@ -20,7 +20,6 @@
 #include "shill/mock_glib.h"
 #include "shill/mock_manager.h"
 #include "shill/mock_metrics.h"
-#include "shill/mock_nss.h"
 #include "shill/mock_ppp_device.h"
 #include "shill/mock_ppp_device_factory.h"
 #include "shill/mock_vpn_service.h"
@@ -56,7 +55,6 @@
                                   kInterfaceName, kInterfaceIndex)),
         certificate_file_(new MockCertificateFile()),
         weak_ptr_factory_(this) {
-    driver_->nss_ = &nss_;
     driver_->certificate_file_.reset(certificate_file_);  // Passes ownership.
   }
 
@@ -189,7 +187,6 @@
   L2TPIPSecDriver *driver_;  // Owned by |service_|.
   scoped_refptr<MockVPNService> service_;
   scoped_refptr<MockPPPDevice> device_;
-  MockNSS nss_;
   MockCertificateFile *certificate_file_;  // Owned by |driver_|.
   base::WeakPtrFactory<L2TPIPSecDriverTest> weak_ptr_factory_;
 };
@@ -284,20 +281,21 @@
 
 TEST_F(L2TPIPSecDriverTest, InitOptions) {
   static const char kHost[] = "192.168.2.254";
-  static const char kCaCertNSS[] = "{1234}";
   static const char kPSK[] = "foobar";
   static const char kXauthUser[] = "silly";
   static const char kXauthPassword[] = "rabbit";
+  const vector<string> kCaCertPEM{ "Insert PEM encoded data here" };
+  static const char kPEMCertfile[] = "/tmp/der-file-from-pem-cert";
+  FilePath pem_cert(kPEMCertfile);
 
   SetArg(kProviderHostProperty, kHost);
-  SetArg(kL2tpIpsecCaCertNssProperty, kCaCertNSS);
   SetArg(kL2tpIpsecPskProperty, kPSK);
   SetArg(kL2tpIpsecXauthUserProperty, kXauthUser);
   SetArg(kL2tpIpsecXauthPasswordProperty, kXauthPassword);
+  SetArgArray(kL2tpIpsecCaCertPemProperty, kCaCertPEM);
 
-  FilePath empty_cert;
-  EXPECT_CALL(nss_, GetDERCertfile(kCaCertNSS, _)).WillOnce(Return(empty_cert));
-
+  EXPECT_CALL(*certificate_file_, CreatePEMFromStrings(kCaCertPEM))
+      .WillOnce(Return(pem_cert));
   const FilePath temp_dir(temp_dir_.path());
   // Once each for PSK and Xauth options.
   EXPECT_CALL(manager_, run_path())
@@ -315,6 +313,7 @@
   ASSERT_FALSE(driver_->xauth_credentials_file_.empty());
   ExpectInFlags(options, "--xauth_credentials_file",
                 driver_->xauth_credentials_file_.value());
+  ExpectInFlags(options, "--server_ca_file", kPEMCertfile);
 }
 
 TEST_F(L2TPIPSecDriverTest, InitPSKOptions) {
@@ -350,27 +349,6 @@
   EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, buf.st_mode);
 }
 
-TEST_F(L2TPIPSecDriverTest, InitNSSOptions) {
-  static const char kHost[] = "192.168.2.254";
-  static const char kCaCertNSS[] = "{1234}";
-  static const char kNSSCertfile[] = "/tmp/nss-cert";
-  FilePath empty_cert;
-  FilePath nss_cert(kNSSCertfile);
-  SetArg(kProviderHostProperty, kHost);
-  SetArg(kL2tpIpsecCaCertNssProperty, kCaCertNSS);
-  EXPECT_CALL(nss_,
-              GetDERCertfile(kCaCertNSS,
-                             ElementsAreArray(kHost, arraysize(kHost) - 1)))
-      .WillOnce(Return(empty_cert))
-      .WillOnce(Return(nss_cert));
-
-  vector<string> options;
-  driver_->InitNSSOptions(&options);
-  EXPECT_TRUE(options.empty());
-  driver_->InitNSSOptions(&options);
-  ExpectInFlags(options, "--server_ca_file", kNSSCertfile);
-}
-
 TEST_F(L2TPIPSecDriverTest, InitPEMOptions) {
   const vector<string> kCaCertPEM{ "Insert PEM encoded data here" };
   static const char kPEMCertfile[] = "/tmp/der-file-from-pem-cert";
diff --git a/mock_eap_credentials.h b/mock_eap_credentials.h
index 36cd45e..5ba09bc 100644
--- a/mock_eap_credentials.h
+++ b/mock_eap_credentials.h
@@ -25,10 +25,8 @@
   MOCK_METHOD2(Load, void(StoreInterface *store, const std::string &id));
   MOCK_CONST_METHOD2(OutputConnectionMetrics,
                      void(Metrics *metrics, Technology::Identifier technology));
-  MOCK_CONST_METHOD4(PopulateSupplicantProperties, void(
+  MOCK_CONST_METHOD2(PopulateSupplicantProperties, void(
       CertificateFile *certificate_file,
-      NSS *nss,
-      const std::vector<char> nss_identifier,
       std::map<std::string, DBus::Variant> *params));
   MOCK_CONST_METHOD1(PopulateWiMaxProperties, void(KeyValueStore *params));
   MOCK_CONST_METHOD3(Save, void(
diff --git a/mock_nss.cc b/mock_nss.cc
deleted file mode 100644
index 78d5603..0000000
--- a/mock_nss.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "shill/mock_nss.h"
-
-namespace shill {
-
-MockNSS::MockNSS() {}
-
-MockNSS::~MockNSS() {}
-
-}  // namespace shill
diff --git a/mock_nss.h b/mock_nss.h
deleted file mode 100644
index ae4f20a..0000000
--- a/mock_nss.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SHILL_MOCK_NSS_
-#define SHILL_MOCK_NSS_
-
-#include <string>
-#include <vector>
-
-#include <gmock/gmock.h>
-
-#include "shill/nss.h"
-
-namespace shill {
-
-class MockNSS : public NSS {
- public:
-  MockNSS();
-  virtual ~MockNSS();
-
-  MOCK_METHOD2(GetPEMCertfile, base::FilePath(const std::string &nickname,
-                                              const std::vector<char> &id));
-  MOCK_METHOD2(GetDERCertfile, base::FilePath(const std::string &nickname,
-                                              const std::vector<char> &id));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockNSS);
-};
-
-}  // namespace shill
-
-#endif  // SHILL_MOCK_NSS_
diff --git a/nss.cc b/nss.cc
deleted file mode 100644
index 36974e3..0000000
--- a/nss.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "shill/nss.h"
-
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-
-#include "shill/logging.h"
-#include "shill/minijail.h"
-
-using base::FilePath;
-using base::HexEncode;
-using base::StringPrintf;
-using std::string;
-using std::vector;
-
-namespace shill {
-
-namespace {
-
-base::LazyInstance<NSS> g_nss = LAZY_INSTANCE_INITIALIZER;
-const char kCertfileBasename[] = "/tmp/nss-cert.";
-const char kNSSGetCert[] = SHIMDIR "/nss-get-cert";
-const char kNSSGetCertUser[] = "chronos";
-
-}  // namespace
-
-NSS::NSS()
-    : minijail_(Minijail::GetInstance()) {
-  SLOG(Crypto, 2) << __func__;
-}
-
-NSS::~NSS() {
-  SLOG(Crypto, 2) << __func__;
-}
-
-// static
-NSS *NSS::GetInstance() {
-  return g_nss.Pointer();
-}
-
-FilePath NSS::GetPEMCertfile(const string &nickname, const vector<char> &id) {
-  return GetCertfile(nickname, id, "pem");
-}
-
-FilePath NSS::GetDERCertfile(const string &nickname, const vector<char> &id) {
-  return GetCertfile(nickname, id, "der");
-}
-
-FilePath NSS::GetCertfile(
-    const string &nickname, const vector<char> &id, const string &type) {
-  string filename =
-      kCertfileBasename + StringToLowerASCII(HexEncode(&id[0], id.size()));
-  vector<char *> args;
-  args.push_back(const_cast<char *>(kNSSGetCert));
-  args.push_back(const_cast<char *>(nickname.c_str()));
-  args.push_back(const_cast<char *>(type.c_str()));
-  args.push_back(const_cast<char *>(filename.c_str()));
-  args.push_back(NULL);
-
-  struct minijail *jail = minijail_->New();
-  minijail_->DropRoot(jail, kNSSGetCertUser);
-
-  int status;
-  if (!minijail_->RunSyncAndDestroy(jail, args, &status)) {
-    LOG(ERROR) << "Unable to spawn " << kNSSGetCert << " in a jail.";
-    return FilePath();
-  }
-
-  if (!WIFEXITED(status) || WEXITSTATUS(status)) {
-    LOG(ERROR) << kNSSGetCert << " failed with status " << status;
-    return FilePath();
-  }
-
-  return FilePath(filename);
-}
-
-}  // namespace shill
diff --git a/nss.h b/nss.h
deleted file mode 100644
index 4b0b1d6..0000000
--- a/nss.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SHILL_NSS_
-#define SHILL_NSS_
-
-#include <string>
-#include <vector>
-
-#include <base/files/file_path.h>
-#include <base/lazy_instance.h>
-#include <gtest/gtest_prod.h>  // for FRIEND_TEST
-
-namespace shill {
-
-class Minijail;
-
-class NSS {
- public:
-  virtual ~NSS();
-
-  // This is a singleton -- use NSS::GetInstance()->Foo().
-  static NSS *GetInstance();
-
-  // Returns an empty path on failure.
-  virtual base::FilePath GetPEMCertfile(const std::string &nickname,
-                                        const std::vector<char> &id);
-
-  // Returns an empty path on failure.
-  virtual base::FilePath GetDERCertfile(const std::string &nickname,
-                                        const std::vector<char> &id);
-
- protected:
-  NSS();
-
- private:
-  friend struct base::DefaultLazyInstanceTraits<NSS>;
-  friend class NSSTest;
-  FRIEND_TEST(NSSTest, GetCertfile);
-
-  base::FilePath GetCertfile(const std::string &nickname,
-                             const std::vector<char> &id,
-                             const std::string &type);
-
-  Minijail *minijail_;
-
-  DISALLOW_COPY_AND_ASSIGN(NSS);
-};
-
-}  // namespace shill
-
-#endif  // SHILL_NSS_
diff --git a/nss_unittest.cc b/nss_unittest.cc
deleted file mode 100644
index f6e3802..0000000
--- a/nss_unittest.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "shill/nss.h"
-
-#include <gtest/gtest.h>
-
-#include "shill/mock_minijail.h"
-
-using std::vector;
-using testing::_;
-using testing::ElementsAre;
-using testing::IsNull;
-using testing::Return;
-using testing::SetArgumentPointee;
-using testing::StrEq;
-
-namespace shill {
-
-class NSSTest : public testing::Test {
- public:
-  NSSTest() :
-      nss_(NSS::GetInstance()) {
-    nss_->minijail_ = &minijail_;
-    test_id_.push_back(0x1a);
-    test_id_.push_back(0x2b);
-  }
-
- protected:
-  vector<char> test_id_;
-  NSS *nss_;
-  MockMinijail minijail_;
-};
-
-TEST_F(NSSTest, GetCertfile) {
-  EXPECT_CALL(minijail_, DropRoot(_, StrEq("chronos"))).Times(3);
-  EXPECT_CALL(minijail_,
-              RunSyncAndDestroy(_,
-                                ElementsAre(_, _,
-                                            StrEq("pem"),
-                                            StrEq("/tmp/nss-cert.1a2b"),
-                                            IsNull()),
-                                _))
-      .WillOnce(Return(false))
-      .WillOnce(DoAll(SetArgumentPointee<2>(1), Return(true)))
-      .WillOnce(DoAll(SetArgumentPointee<2>(0), Return(true)));
-  EXPECT_TRUE(nss_->GetCertfile("foo", test_id_, "pem").empty());
-  EXPECT_TRUE(nss_->GetCertfile("foo", test_id_, "pem").empty());
-  EXPECT_FALSE(nss_->GetCertfile("foo", test_id_, "pem").empty());
-}
-
-TEST_F(NSSTest, GetPEMCertfile) {
-  EXPECT_CALL(minijail_, DropRoot(_, StrEq("chronos")));
-  EXPECT_CALL(minijail_,
-              RunSyncAndDestroy(_,
-                                ElementsAre(_, _,
-                                            StrEq("pem"),
-                                            StrEq("/tmp/nss-cert.1a2b"),
-                                            IsNull()),
-                                _))
-      .WillOnce(DoAll(SetArgumentPointee<2>(0), Return(true)));
-  EXPECT_FALSE(nss_->GetPEMCertfile("foo", test_id_).empty());
-}
-
-TEST_F(NSSTest, GetDERCertfile) {
-  EXPECT_CALL(minijail_, DropRoot(_, StrEq("chronos")));
-  EXPECT_CALL(minijail_,
-              RunSyncAndDestroy(_,
-                                ElementsAre(_, _,
-                                            StrEq("der"),
-                                            StrEq("/tmp/nss-cert.1a2b"),
-                                            IsNull()),
-                                _))
-      .WillOnce(DoAll(SetArgumentPointee<2>(0), Return(true)));
-  EXPECT_FALSE(nss_->GetDERCertfile("foo", test_id_).empty());
-}
-
-}  // namespace shill
diff --git a/openvpn_driver.cc b/openvpn_driver.cc
index a25d43d..b1cce50 100644
--- a/openvpn_driver.cc
+++ b/openvpn_driver.cc
@@ -19,7 +19,6 @@
 #include "shill/error.h"
 #include "shill/logging.h"
 #include "shill/manager.h"
-#include "shill/nss.h"
 #include "shill/openvpn_management_server.h"
 #include "shill/process_killer.h"
 #include "shill/rpc_task.h"
@@ -146,7 +145,6 @@
       device_info_(device_info),
       glib_(glib),
       management_server_(new OpenVPNManagementServer(this, glib)),
-      nss_(NSS::GetInstance()),
       certificate_file_(new CertificateFile()),
       extra_certificates_file_(new CertificateFile()),
       process_killer_(ProcessKiller::GetInstance()),
@@ -722,8 +720,6 @@
     vector<vector<string>> *options, Error *error) {
   string ca_cert =
       args()->LookupString(kOpenVPNCaCertProperty, "");
-  string ca_cert_nss =
-      args()->LookupString(kOpenVPNCaCertNSSProperty, "");
   vector<string> ca_cert_pem;
   if (args()->ContainsStrings(kOpenVPNCaCertPemProperty)) {
     ca_cert_pem = args()->GetStrings(kOpenVPNCaCertPemProperty);
@@ -732,8 +728,6 @@
   int num_ca_cert_types = 0;
   if (!ca_cert.empty())
       num_ca_cert_types++;
-  if (!ca_cert_nss.empty())
-      num_ca_cert_types++;
   if (!ca_cert_pem.empty())
       num_ca_cert_types++;
   if (num_ca_cert_types == 0) {
@@ -743,26 +737,12 @@
   } else if (num_ca_cert_types > 1) {
     Error::PopulateAndLog(
         error, Error::kInvalidArguments,
-        "Can't specify more than one of CACert, CACertNSS and CACertPEM.");
+        "Can't specify more than one of CACert and CACertPEM.");
     return false;
   }
   string cert_file;
-  if (!ca_cert_nss.empty()) {
-    DCHECK(ca_cert.empty() && ca_cert_pem.empty());
-    const string &vpnhost = args()->GetString(kProviderHostProperty);
-    vector<char> id(vpnhost.begin(), vpnhost.end());
-    FilePath certfile = nss_->GetPEMCertfile(ca_cert_nss, id);
-    if (certfile.empty()) {
-      Error::PopulateAndLog(
-          error,
-          Error::kInvalidArguments,
-          "Unable to extract NSS CA certificate: " + ca_cert_nss);
-      return false;
-    }
-    AppendOption("ca", certfile.value(), options);
-    return true;
-  } else if (!ca_cert_pem.empty()) {
-    DCHECK(ca_cert.empty() && ca_cert_nss.empty());
+  if (!ca_cert_pem.empty()) {
+    DCHECK(ca_cert.empty());
     FilePath certfile = certificate_file_->CreatePEMFromStrings(ca_cert_pem);
     if (certfile.empty()) {
       Error::PopulateAndLog(
@@ -774,7 +754,7 @@
     AppendOption("ca", certfile.value(), options);
     return true;
   }
-  DCHECK(!ca_cert.empty() && ca_cert_nss.empty() && ca_cert_pem.empty());
+  DCHECK(!ca_cert.empty() && ca_cert_pem.empty());
   AppendOption("ca", ca_cert, options);
   return true;
 }
@@ -1068,8 +1048,7 @@
       Metrics::kVpnDriverOpenVpn,
       Metrics::kMetricVpnDriverMax);
 
-  if (args()->LookupString(kOpenVPNCaCertNSSProperty, "") != "" ||
-      args()->LookupString(kOpenVPNCaCertProperty, "") != "" ||
+  if (args()->LookupString(kOpenVPNCaCertProperty, "") != "" ||
       (args()->ContainsStrings(kOpenVPNCaCertPemProperty) &&
        !args()->GetStrings(kOpenVPNCaCertPemProperty).empty())) {
     metrics_->SendEnumToUMA(
diff --git a/openvpn_driver.h b/openvpn_driver.h
index b44b7a4..8294ae2 100644
--- a/openvpn_driver.h
+++ b/openvpn_driver.h
@@ -35,7 +35,6 @@
 class DeviceInfo;
 class Error;
 class Metrics;
-class NSS;
 class OpenVPNManagementServer;
 class ProcessKiller;
 
@@ -260,7 +259,6 @@
   GLib *glib_;
   Sockets sockets_;
   scoped_ptr<OpenVPNManagementServer> management_server_;
-  NSS *nss_;
   scoped_ptr<CertificateFile> certificate_file_;
   scoped_ptr<CertificateFile> extra_certificates_file_;
   ProcessKiller *process_killer_;
diff --git a/openvpn_driver_unittest.cc b/openvpn_driver_unittest.cc
index 71ae784..35c0d3b 100644
--- a/openvpn_driver_unittest.cc
+++ b/openvpn_driver_unittest.cc
@@ -25,7 +25,6 @@
 #include "shill/mock_glib.h"
 #include "shill/mock_manager.h"
 #include "shill/mock_metrics.h"
-#include "shill/mock_nss.h"
 #include "shill/mock_openvpn_management_server.h"
 #include "shill/mock_process_killer.h"
 #include "shill/mock_service.h"
@@ -104,7 +103,6 @@
         extra_certificates_file_(new MockCertificateFile()),
         management_server_(new NiceMock<MockOpenVPNManagementServer>()) {
     driver_->management_server_.reset(management_server_);
-    driver_->nss_ = &nss_;
     driver_->certificate_file_.reset(certificate_file_);  // Passes ownership.
     driver_->extra_certificates_file_.reset(
         extra_certificates_file_);  // Passes ownership.
@@ -256,7 +254,6 @@
   scoped_refptr<MockVirtualDevice> device_;
   MockCertificateFile *certificate_file_;  // Owned by |driver_|.
   MockCertificateFile *extra_certificates_file_;  // Owned by |driver_|.
-  MockNSS nss_;
   MockProcessKiller process_killer_;
   base::ScopedTempDir temporary_directory_;
 
@@ -761,7 +758,6 @@
   static const char kHost[] = "192.168.2.254";
   static const char kCaCert[] = "foo";
   static const char kCaCertNSS[] = "{1234}";
-  static const char kNSSCertfile[] = "/tmp/nss-cert";
 
   Error error;
   vector<vector<string>> options;
@@ -775,42 +771,30 @@
   ExpectInFlags(options, "ca", kCaCert);
   EXPECT_TRUE(error.IsSuccess());
 
+  // We should ignore the CaCertNSS property.
   SetArg(kOpenVPNCaCertNSSProperty, kCaCertNSS);
-  EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
-  EXPECT_EQ(Error::kInvalidArguments, error.type());
-  EXPECT_EQ("Can't specify more than one of CACert, CACertNSS and CACertPEM.",
-            error.message());
+  EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
+  ExpectInFlags(options, "ca", kCaCert);
+  EXPECT_TRUE(error.IsSuccess());
 
   SetArg(kOpenVPNCaCertProperty, "");
   SetArg(kProviderHostProperty, kHost);
   FilePath empty_cert;
-  FilePath nss_cert(kNSSCertfile);
-  EXPECT_CALL(nss_,
-              GetPEMCertfile(kCaCertNSS,
-                             ElementsAreArray(kHost, arraysize(kHost) - 1)))
-      .WillOnce(Return(empty_cert))
-      .WillOnce(Return(nss_cert));
-
   error.Reset();
-  EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
-  EXPECT_EQ(Error::kInvalidArguments, error.type());
-  EXPECT_EQ("Unable to extract NSS CA certificate: {1234}", error.message());
-
-  error.Reset();
-  options.clear();
   EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
-  ExpectInFlags(options, "ca", kNSSCertfile);
+  ExpectInFlags(options, "ca", OpenVPNDriver::kDefaultCACertificates);
   EXPECT_TRUE(error.IsSuccess());
 
+  SetArg(kOpenVPNCaCertProperty, kCaCert);
   const vector<string> kCaCertPEM{ "---PEM CONTENTS---" };
   SetArgArray(kOpenVPNCaCertPemProperty, kCaCertPEM);
   EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
   EXPECT_EQ(Error::kInvalidArguments, error.type());
-  EXPECT_EQ("Can't specify more than one of CACert, CACertNSS and CACertPEM.",
+  EXPECT_EQ("Can't specify more than one of CACert and CACertPEM.",
             error.message());
 
   options.clear();
-  SetArg(kOpenVPNCaCertNSSProperty, "");
+  SetArg(kOpenVPNCaCertProperty, "");
   SetArg(kProviderHostProperty, "");
   static const char kPEMCertfile[] = "/tmp/pem-cert";
   FilePath pem_cert(kPEMCertfile);
diff --git a/shill.gyp b/shill.gyp
index 8603361..8fbb89b 100644
--- a/shill.gyp
+++ b/shill.gyp
@@ -358,7 +358,6 @@
         'netlink_socket.cc',
         'nl80211_attribute.cc',
         'nl80211_message.cc',
-        'nss.cc',
         'pending_activation_store.cc',
         'portal_detector.cc',
         'power_manager.cc',
@@ -444,20 +443,6 @@
       ]
     },
     {
-      'target_name': 'nss-get-cert',
-      'type': 'executable',
-      'dependencies': ['libshill'],
-      'variables': {
-        'deps': [
-          'nss',
-        ],
-      },
-      'sources': [
-        'shims/certificates.cc',
-        'shims/nss_get_cert.cc',
-      ]
-    },
-    {
       'target_name': 'netfilter-queue-helper',
       'type': 'executable',
       'variables': {
@@ -529,7 +514,6 @@
           'includes': ['../../platform2/common-mk/common_test.gypi'],
           'variables': {
             'deps': [
-              'nss',
               'libnetfilter_queue',
               'libnfnetlink',
             ],
@@ -626,7 +610,6 @@
             'mock_metrics.cc',
             'mock_minijail.cc',
             'mock_netlink_manager.cc',
-            'mock_nss.cc',
             'mock_pending_activation_store.cc',
             'mock_portal_detector.cc',
             'mock_power_manager.cc',
@@ -661,7 +644,6 @@
             'netlink_message_unittest.cc',
             'netlink_socket_unittest.cc',
             'nice_mock_control.cc',
-            'nss_unittest.cc',
             'pending_activation_store_unittest.cc',
             'portal_detector_unittest.cc',
             'power_manager_unittest.cc',
@@ -686,8 +668,6 @@
             'service_unittest.cc',
             'shill_time_unittest.cc',
             'shill_unittest.cc',
-            'shims/certificates.cc',
-            'shims/certificates_unittest.cc',
             'shims/netfilter_queue_processor.cc',
             'shims/netfilter_queue_processor_unittest.cc',
             'socket_info_reader_unittest.cc',
diff --git a/shill_daemon.cc b/shill_daemon.cc
index 3e36848..51378eb 100644
--- a/shill_daemon.cc
+++ b/shill_daemon.cc
@@ -15,7 +15,6 @@
 #include "shill/logging.h"
 #include "shill/netlink_manager.h"
 #include "shill/nl80211_message.h"
-#include "shill/nss.h"
 #include "shill/proxy_factory.h"
 #include "shill/routing_table.h"
 #include "shill/rtnl_handler.h"
@@ -31,7 +30,6 @@
     : config_(config),
       control_(control),
       metrics_(new Metrics(&dispatcher_)),
-      nss_(NSS::GetInstance()),
       proxy_factory_(ProxyFactory::GetInstance()),
       rtnl_handler_(RTNLHandler::GetInstance()),
       routing_table_(RoutingTable::GetInstance()),
diff --git a/shill_daemon.h b/shill_daemon.h
index f3aae42..e0f7eea 100644
--- a/shill_daemon.h
+++ b/shill_daemon.h
@@ -24,7 +24,6 @@
 class GLib;
 class Metrics;
 class NetlinkManager;
-class NSS;
 class ProxyFactory;
 class RoutingTable;
 class RTNLHandler;
@@ -61,7 +60,6 @@
   GLib glib_;
   Sockets sockets_;
   scoped_ptr<Metrics> metrics_;
-  NSS *nss_;
   ProxyFactory *proxy_factory_;
   RTNLHandler *rtnl_handler_;
   RoutingTable *routing_table_;
diff --git a/shims/certificates.cc b/shims/certificates.cc
deleted file mode 100644
index af63768..0000000
--- a/shims/certificates.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <base64.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-
-#include <string>
-
-#include <base/files/file_path.h>
-#include <base/file_util.h>
-#include <base/logging.h>
-
-#include "shill/byte_string.h"
-#include "shill/shims/certificates.h"
-
-using std::string;
-
-namespace {
-
-const char kPEMHeader[] = "-----BEGIN CERTIFICATE-----\n";
-const char kPEMFooter[] = "\n-----END CERTIFICATE-----\n";
-
-}  // namespace
-
-namespace shill {
-
-namespace shims {
-
-// static
-ByteString Certificates::ConvertDERToPEM(const ByteString &der_cert) {
-  char *pem_data =
-      BTOA_DataToAscii(der_cert.GetConstData(), der_cert.GetLength());
-  ByteString pem_cert(kPEMHeader + string(pem_data) + kPEMFooter, false);
-  free(pem_data);
-  return pem_cert;
-}
-
-// static
-bool Certificates::Write(const ByteString &cert,
-                         const base::FilePath &certfile) {
-  if (base::WriteFile(certfile,
-                      reinterpret_cast<const char *>(cert.GetConstData()),
-                      cert.GetLength()) != static_cast<int>(cert.GetLength())) {
-    base::DeleteFile(certfile, false);
-    LOG(ERROR) << "Unable to save certificate to a file: " << certfile.value();
-    return false;
-  }
-  chmod(certfile.value().c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-  return true;
-}
-
-}  // namespace shims
-
-}  // namespace shill
diff --git a/shims/certificates.h b/shims/certificates.h
deleted file mode 100644
index 96ad36a..0000000
--- a/shims/certificates.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SHILL_SHIMS_CERTIFICATES_H_
-#define SHILL_SHIMS_CERTIFICATES_H_
-
-#include "shill/byte_string.h"
-
-namespace base {
-
-class FilePath;
-
-}  // namespace base
-
-namespace shill {
-
-namespace shims {
-
-class Certificates {
- public:
-  static ByteString ConvertDERToPEM(const ByteString &der_cert);
-
-  static bool Write(const ByteString &cert, const base::FilePath &certfile);
-};
-
-}  // namespace shims
-
-}  // namespace shill
-
-#endif  // SHILL_SHIMS_CERTIFICATES_H_
diff --git a/shims/certificates_unittest.cc b/shims/certificates_unittest.cc
deleted file mode 100644
index 4889533..0000000
--- a/shims/certificates_unittest.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "shill/shims/certificates.h"
-
-#include <sys/stat.h>
-
-#include <base/files/file_path.h>
-#include <base/file_util.h>
-#include <base/files/scoped_temp_dir.h>
-#include <gtest/gtest.h>
-
-using std::string;
-using testing::Test;
-
-namespace shill {
-
-namespace shims {
-
-class CertificatesTest : public Test {
-};
-
-TEST_F(CertificatesTest, ConvertDERToPEM) {
-  ByteString der_cert(
-      string("01234567890123456789012345678901234567890123456789"), false);
-  ByteString expected_pem_cert(
-      string(
-          "-----BEGIN CERTIFICATE-----\n"
-          "MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3\r\n"
-          "ODk=\n"
-          "-----END CERTIFICATE-----\n"),
-      false);
-  ByteString pem_cert = Certificates::ConvertDERToPEM(der_cert);
-  EXPECT_TRUE(expected_pem_cert.Equals(pem_cert));
-}
-
-TEST_F(CertificatesTest, Write) {
-  string cert_str = "foo";
-  ByteString cert(cert_str, false);
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  base::FilePath certfile = temp_dir.path().Append("certfile");
-  EXPECT_TRUE(Certificates::Write(cert, certfile));
-  string contents;
-  EXPECT_TRUE(base::ReadFileToString(certfile, &contents));
-  EXPECT_EQ(cert_str, contents);
-  struct stat buf;
-  EXPECT_EQ(0, stat(certfile.value().c_str(), &buf));
-  EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, buf.st_mode);
-
-  EXPECT_FALSE(Certificates::Write(cert, temp_dir.path().Append("foo/bar")));
-}
-
-}  // namespace shims
-
-}  // namespace shill
diff --git a/shims/nss_get_cert.cc b/shims/nss_get_cert.cc
deleted file mode 100644
index 77def53..0000000
--- a/shims/nss_get_cert.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cert.h>
-#include <nspr.h>
-#include <nss.h>
-
-#include <string>
-
-#include <base/command_line.h>
-#include <base/files/file_path.h>
-#include <base/logging.h>
-#include <chromeos/syslog_logging.h>
-
-#include "shill/byte_string.h"
-#include "shill/shims/certificates.h"
-
-using shill::ByteString;
-using shill::shims::Certificates;
-using std::string;
-
-namespace {
-
-const char kCertDBDir[] = "sql:/home/chronos/user/.pki/nssdb";
-
-class ScopedNSS {
- public:
-  ScopedNSS() : initialized_(false) {}
-  ~ScopedNSS();
-
-  bool Init(const string &config_dir);
-
- private:
-  bool initialized_;
-};
-
-ScopedNSS::~ScopedNSS() {
-  if (initialized_) {
-    NSS_Shutdown();
-    initialized_ = false;
-  }
-}
-
-bool ScopedNSS::Init(const string &config_dir) {
-  if (!initialized_ && (NSS_Init(config_dir.c_str()) != SECSuccess)) {
-    LOG(ERROR) << "Unable to initialize NSS in " << config_dir
-               << ". Error code: " << PR_GetError();
-    return false;
-  }
-  initialized_ = true;
-  return true;
-}
-
-bool GetDERCertificate(const string &nickname, ByteString *der_cert) {
-  CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
-  if (!handle) {
-    LOG(ERROR) << "Null certificate database handle.";
-    return false;
-  }
-  CERTCertificate *cert = CERT_FindCertByNickname(handle, nickname.c_str());
-  if (!cert) {
-    LOG(ERROR) << "Couldn't find certificate: " << nickname;
-    return false;
-  }
-  *der_cert = ByteString(cert->derCert.data, cert->derCert.len);
-  CERT_DestroyCertificate(cert);
-  return true;
-}
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  CommandLine::Init(argc, argv);
-  chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogHeader);
-  if (argc != 4) {
-    LOG(ERROR) << "Usage: nss-get-cert <cert-nickname> <der|pem> <outfile>";
-    return EXIT_FAILURE;
-  }
-
-  const string nickname = argv[1];
-  const string format_str = argv[2];
-  const base::FilePath outfile(argv[3]);
-
-  ScopedNSS nss;
-  ByteString cert;
-  if (!nss.Init(kCertDBDir) || !GetDERCertificate(nickname, &cert)) {
-    return EXIT_FAILURE;
-  }
-  if (format_str == "pem") {
-    cert = Certificates::ConvertDERToPEM(cert);
-  } else if (format_str != "der") {
-    LOG(ERROR) << "Invalid format parameter: " << format_str;
-    return EXIT_FAILURE;
-  }
-  return Certificates::Write(cert, outfile) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
diff --git a/test-scripts/connect-vpn b/test-scripts/connect-vpn
index 154e9f4..b91fc7f 100755
--- a/test-scripts/connect-vpn
+++ b/test-scripts/connect-vpn
@@ -109,7 +109,7 @@
                 params["Provider.Host"] = args[2]
                 params["VPN.Domain"] = args[3]
                 if vpn_type == "l2tpipsec-cert" and len(args) == 10:
-                    params["L2TPIPsec.CACertNSS"] = args[4]
+                    params["L2TPIPsec.CACertPEM"] = [ args[4] ]
                     params["L2TPIPsec.ClientCertSlot"] = args[5]
                     params["L2TPIPsec.ClientCertID"] = args[6]
                     params["L2TPIPsec.PIN"] = args[7]
@@ -117,7 +117,7 @@
                     params["L2TPIPsec.User"] = args[8]
                     params["L2TPIPsec.Password"] = args[9]
                 elif vpn_type == "l2tpipsec-psk" and len(args) == 7:
-                    params["L2TPIPsec.CACertNSS"] = ""
+                    params["L2TPIPsec.CACertPEM"] = []
                     params["L2TPIPsec.ClientCertSlot"] = ""
                     params["L2TPIPsec.ClientCertID"] = ""
                     params["L2TPIPsec.PIN"] = ""
diff --git a/wifi_service.cc b/wifi_service.cc
index 287c7b3..01aa427 100644
--- a/wifi_service.cc
+++ b/wifi_service.cc
@@ -28,7 +28,6 @@
 #include "shill/logging.h"
 #include "shill/manager.h"
 #include "shill/metrics.h"
-#include "shill/nss.h"
 #include "shill/property_accessor.h"
 #include "shill/store_interface.h"
 #include "shill/wifi.h"
@@ -78,7 +77,6 @@
       ssid_(ssid),
       ieee80211w_required_(false),
       expecting_disconnect_(false),
-      nss_(NSS::GetInstance()),
       certificate_file_(new CertificateFile()),
       provider_(provider) {
   PropertyStore *store = this->mutable_store();
@@ -578,9 +576,7 @@
   }
 
   if (Is8021x()) {
-    vector<char> nss_identifier(ssid_.begin(), ssid_.end());
-    eap()->PopulateSupplicantProperties(
-        certificate_file_.get(), nss_, nss_identifier, &params);
+    eap()->PopulateSupplicantProperties(certificate_file_.get(), &params);
   } else if (security_ == kSecurityPsk ||
              security_ == kSecurityRsn ||
              security_ == kSecurityWpa) {
diff --git a/wifi_service.h b/wifi_service.h
index 9e0319d..f0c31a4 100644
--- a/wifi_service.h
+++ b/wifi_service.h
@@ -26,7 +26,6 @@
 class Error;
 class Manager;
 class Metrics;
-class NSS;
 class WiFiProvider;
 
 class WiFiService : public Service {
@@ -305,7 +304,6 @@
   // Flag indicating if service disconnect is initiated by user for
   // connecting to other service.
   bool expecting_disconnect_;
-  NSS *nss_;
   scoped_ptr<CertificateFile> certificate_file_;
   // Bare pointer is safe because WiFi service instances are owned by
   // the WiFiProvider and are guaranteed to be deallocated by the time
diff --git a/wifi_service_unittest.cc b/wifi_service_unittest.cc
index 9f4f3af..940988d 100644
--- a/wifi_service_unittest.cc
+++ b/wifi_service_unittest.cc
@@ -26,7 +26,6 @@
 #include "shill/mock_eap_credentials.h"
 #include "shill/mock_log.h"
 #include "shill/mock_manager.h"
-#include "shill/mock_nss.h"
 #include "shill/mock_profile.h"
 #include "shill/mock_service.h"
 #include "shill/mock_store.h"
@@ -542,7 +541,7 @@
   service->OnEapCredentialsChanged();
   service->Connect(NULL, "in test");
 
-  EXPECT_CALL(*eap, PopulateSupplicantProperties(_, _, _, _));
+  EXPECT_CALL(*eap, PopulateSupplicantProperties(_, _));
   // The mocked function does not actually set EAP parameters so we cannot
   // expect them to be set.
   service->GetSupplicantConfigurationParameters();
diff --git a/wpa_supplicant.cc b/wpa_supplicant.cc
index a41ac63..30a117d 100644
--- a/wpa_supplicant.cc
+++ b/wpa_supplicant.cc
@@ -6,18 +6,11 @@
 
 #include <map>
 #include <string>
-#include <vector>
 
-#include <base/files/file_path.h>
+#include "shill/logging.h"
 
-#include "shill/certificate_file.h"
-#include "shill/eap_credentials.h"
-#include "shill/nss.h"
-
-using base::FilePath;
 using std::map;
 using std::string;
-using std::vector;
 
 namespace shill {
 
@@ -152,8 +145,8 @@
 
 // static
 bool WPASupplicant::ExtractRemoteCertification(
-      const std::map<std::string, DBus::Variant> &properties,
-      std::string *subject, uint32 *depth) {
+      const map<string, DBus::Variant> &properties,
+      string *subject, uint32 *depth) {
   map<string, ::DBus::Variant>::const_iterator depth_it =
       properties.find(WPASupplicant::kInterfacePropertyDepth);
   if (depth_it == properties.end()) {