Make x509_certificate_model_nss functions take CERTCertificate instead of OSCertHandle.

Renames x509_certificate_model.h to x509_certificate_model_nss.h.

Bug: 671420
Change-Id: I6b6c3bdd5e0d9b21dbf9a0bbaa56597d14d794ab
Reviewed-on: https://chromium-review.googlesource.com/612409
Commit-Queue: Matt Mueller <[email protected]>
Reviewed-by: Scott Violet <[email protected]>
Reviewed-by: David Benjamin <[email protected]>
Cr-Commit-Position: refs/heads/master@{#495484}
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc
index aa45bb0c..fbfa181 100644
--- a/chrome/browser/certificate_manager_model.cc
+++ b/chrome/browser/certificate_manager_model.cc
@@ -14,7 +14,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/net/nss_context.h"
 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h"
-#include "chrome/common/net/x509_certificate_model.h"
+#include "chrome/common/net/x509_certificate_model_nss.h"
 #include "chrome/grit/generated_resources.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/ui/certificate_dialogs.cc b/chrome/browser/ui/certificate_dialogs.cc
index a4de34d..813299c 100644
--- a/chrome/browser/ui/certificate_dialogs.cc
+++ b/chrome/browser/ui/certificate_dialogs.cc
@@ -16,7 +16,7 @@
 #include "base/logging.h"
 #include "base/task_scheduler/post_task.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
-#include "chrome/common/net/x509_certificate_model.h"
+#include "chrome/common/net/x509_certificate_model_nss.h"
 #include "chrome/grit/generated_resources.h"
 #include "net/base/filename_util.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.cc b/chrome/browser/ui/webui/certificate_viewer_webui.cc
index eae1c60..caf4dd1 100644
--- a/chrome/browser/ui/webui/certificate_viewer_webui.cc
+++ b/chrome/browser/ui/webui/certificate_viewer_webui.cc
@@ -23,7 +23,7 @@
 #include "chrome/browser/ui/certificate_dialogs.h"
 #include "chrome/browser/ui/webui/certificate_viewer_ui.h"
 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
-#include "chrome/common/net/x509_certificate_model.h"
+#include "chrome/common/net/x509_certificate_model_nss.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/common/net/BUILD.gn b/chrome/common/net/BUILD.gn
index 73bc725..68597d6 100644
--- a/chrome/common/net/BUILD.gn
+++ b/chrome/common/net/BUILD.gn
@@ -10,9 +10,6 @@
   sources = [
     "net_resource_provider.cc",
     "net_resource_provider.h",
-    "x509_certificate_model.cc",
-    "x509_certificate_model.h",
-    "x509_certificate_model_nss.cc",
   ]
 
   configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
@@ -30,18 +27,16 @@
     "//ui/base",
   ]
 
-  if (is_android) {
-    sources -= [ "x509_certificate_model.cc" ]
-  }
-
   if (use_nss_certs) {
+    sources += [
+      "x509_certificate_model_nss.cc",
+      "x509_certificate_model_nss.h",
+    ]
     deps += [
       "//chrome/third_party/mozilla_security_manager",
       "//crypto:platform",
     ]
     allow_circular_includes_from =
         [ "//chrome/third_party/mozilla_security_manager" ]
-  } else {
-    sources -= [ "x509_certificate_model_nss.cc" ]
   }
 }
diff --git a/chrome/common/net/x509_certificate_model.cc b/chrome/common/net/x509_certificate_model.cc
deleted file mode 100644
index 3493dbe..0000000
--- a/chrome/common/net/x509_certificate_model.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2011 The Chromium 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 "chrome/common/net/x509_certificate_model.h"
-
-#include <unicode/uidna.h>
-
-#include <algorithm>
-
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/url_formatter/url_formatter.h"
-#include "ui/base/l10n/l10n_util.h"
-
-namespace x509_certificate_model {
-
-std::string ProcessIDN(const std::string& input) {
-  // Convert the ASCII input to a string16 for ICU.
-  base::string16 input16;
-  input16.reserve(input.length());
-  input16.insert(input16.end(), input.begin(), input.end());
-
-  base::string16 output16 = url_formatter::IDNToUnicode(input);
-  if (input16 == output16)
-    return input;  // Input did not contain any encoded data.
-
-  // Input contained encoded data, return formatted string showing original and
-  // decoded forms.
-  return l10n_util::GetStringFUTF8(IDS_CERT_INFO_IDN_VALUE_FORMAT,
-                                   input16, output16);
-}
-
-std::string ProcessRawBytesWithSeparators(const unsigned char* data,
-                                          size_t data_length,
-                                          char hex_separator,
-                                          char line_separator) {
-  static const char kHexChars[] = "0123456789ABCDEF";
-
-  // Each input byte creates two output hex characters + a space or newline,
-  // except for the last byte.
-  std::string ret;
-  size_t kMin = 0U;
-
-  if (!data_length)
-    return std::string();
-
-  ret.reserve(std::max(kMin, data_length * 3 - 1));
-
-  for (size_t i = 0; i < data_length; ++i) {
-    unsigned char b = data[i];
-    ret.push_back(kHexChars[(b >> 4) & 0xf]);
-    ret.push_back(kHexChars[b & 0xf]);
-    if (i + 1 < data_length) {
-      if ((i + 1) % 16 == 0)
-        ret.push_back(line_separator);
-      else
-        ret.push_back(hex_separator);
-    }
-  }
-  return ret;
-}
-
-std::string ProcessRawBytes(const unsigned char* data, size_t data_length) {
-  return ProcessRawBytesWithSeparators(data, data_length, ' ', '\n');
-}
-
-#if defined(USE_NSS_CERTS)
-std::string ProcessRawBits(const unsigned char* data, size_t data_length) {
-  return ProcessRawBytes(data, (data_length + 7) / 8);
-}
-#endif  // USE_NSS_CERTS
-
-}  // namespace x509_certificate_model
-
diff --git a/chrome/common/net/x509_certificate_model.h b/chrome/common/net/x509_certificate_model.h
deleted file mode 100644
index 6a8987a..0000000
--- a/chrome/common/net/x509_certificate_model.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2011 The Chromium 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 CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_H_
-#define CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_H_
-
-#include <stddef.h>
-
-#include "net/cert/cert_type.h"
-#include "net/cert/x509_certificate.h"
-
-// This namespace defines a set of functions to be used in UI-related bits of
-// X509 certificates. It decouples the UI from the underlying crypto library
-// (currently NSS or OpenSSL - in development).
-// This is currently only used by linux, as mac / windows use their own native
-// certificate viewers and crypto libraries.
-namespace x509_certificate_model {
-
-std::string GetCertNameOrNickname(
-    net::X509Certificate::OSCertHandle cert_handle);
-
-std::string GetTokenName(net::X509Certificate::OSCertHandle cert_handle);
-
-std::string GetVersion(net::X509Certificate::OSCertHandle cert_handle);
-
-net::CertType GetType(net::X509Certificate::OSCertHandle cert_handle);
-
-void GetUsageStrings(
-    net::X509Certificate::OSCertHandle cert_handle,
-    std::vector<std::string>* usages);
-
-std::string GetSerialNumberHexified(
-    net::X509Certificate::OSCertHandle cert_handle,
-    const std::string& alternative_text);
-
-std::string GetIssuerCommonName(
-    net::X509Certificate::OSCertHandle cert_handle,
-    const std::string& alternative_text);
-
-std::string GetIssuerOrgName(
-    net::X509Certificate::OSCertHandle cert_handle,
-    const std::string& alternative_text);
-
-std::string GetIssuerOrgUnitName(
-    net::X509Certificate::OSCertHandle cert_handle,
-    const std::string& alternative_text);
-
-std::string GetSubjectOrgName(
-    net::X509Certificate::OSCertHandle cert_handle,
-    const std::string& alternative_text);
-
-std::string GetSubjectOrgUnitName(
-    net::X509Certificate::OSCertHandle cert_handle,
-    const std::string& alternative_text);
-
-std::string GetSubjectCommonName(
-    net::X509Certificate::OSCertHandle cert_handle,
-    const std::string& alternative_text);
-
-bool GetTimes(net::X509Certificate::OSCertHandle cert_handle,
-              base::Time* issued, base::Time* expires);
-
-std::string GetTitle(net::X509Certificate::OSCertHandle cert_handle);
-std::string GetIssuerName(net::X509Certificate::OSCertHandle cert_handle);
-std::string GetSubjectName(net::X509Certificate::OSCertHandle cert_handle);
-
-struct Extension {
-  std::string name;
-  std::string value;
-};
-
-typedef std::vector<Extension> Extensions;
-
-void GetExtensions(
-    const std::string& critical_label,
-    const std::string& non_critical_label,
-    net::X509Certificate::OSCertHandle cert_handle,
-    Extensions* extensions);
-
-// Hash a certificate using the given algorithm, return the result as a
-// colon-seperated hex string.
-std::string HashCertSHA256(net::X509Certificate::OSCertHandle cert_handle);
-std::string HashCertSHA1(net::X509Certificate::OSCertHandle cert_handle);
-
-// For host values, if they contain IDN Punycode-encoded A-labels, this will
-// return a string suitable for display that contains both the original and the
-// decoded U-label form.  Otherwise, the string will be returned as is.
-std::string ProcessIDN(const std::string& input);
-
-std::string GetCMSString(const net::X509Certificate::OSCertHandles& cert_chain,
-                         size_t start, size_t end);
-
-std::string ProcessSecAlgorithmSignature(
-    net::X509Certificate::OSCertHandle cert_handle);
-std::string ProcessSecAlgorithmSubjectPublicKey(
-    net::X509Certificate::OSCertHandle cert_handle);
-std::string ProcessSecAlgorithmSignatureWrap(
-    net::X509Certificate::OSCertHandle cert_handle);
-
-std::string ProcessSubjectPublicKeyInfo(
-    net::X509Certificate::OSCertHandle cert_handle);
-
-std::string ProcessRawBitsSignatureWrap(
-    net::X509Certificate::OSCertHandle cert_handle);
-
-// Format a buffer as |hex_separator| separated string, with 16 bytes on each
-// line separated using |line_separator|.
-std::string ProcessRawBytesWithSeparators(const unsigned char* data,
-                                          size_t data_length,
-                                          char hex_separator,
-                                          char line_separator);
-
-// Format a buffer as a space separated string, with 16 bytes on each line.
-std::string ProcessRawBytes(const unsigned char* data,
-                            size_t data_length);
-
-#if defined(USE_NSS_CERTS)
-// Format a buffer as a space separated string, with 16 bytes on each line.
-// |data_length| is the length in bits.
-std::string ProcessRawBits(const unsigned char* data,
-                           size_t data_length);
-#endif  // USE_NSS_CERTS
-
-}  // namespace x509_certificate_model
-
-#endif  // CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_H_
diff --git a/chrome/common/net/x509_certificate_model_nss.cc b/chrome/common/net/x509_certificate_model_nss.cc
index 7289dc00..3f72ea5 100644
--- a/chrome/common/net/x509_certificate_model_nss.cc
+++ b/chrome/common/net/x509_certificate_model_nss.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/common/net/x509_certificate_model.h"
+#include "chrome/common/net/x509_certificate_model_nss.h"
 
 #include <cert.h>
 #include <cms.h>
@@ -15,18 +15,24 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <string.h>
+#include <unicode/uidna.h>
 
+#include <algorithm>
 #include <memory>
 
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/grit/generated_resources.h"
 #include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h"
 #include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h"
 #include "chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.h"
+#include "components/url_formatter/url_formatter.h"
 #include "crypto/nss_util.h"
 #include "crypto/scoped_nss_types.h"
-#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util_nss.h"
+#include "ui/base/l10n/l10n_util.h"
 
 namespace psm = mozilla_security_manager;
 
@@ -75,7 +81,7 @@
   return criticality + "\n" + psm::ProcessExtensionData(extension);
 }
 
-std::string GetNickname(net::X509Certificate::OSCertHandle cert_handle) {
+std::string GetNickname(CERTCertificate* cert_handle) {
   std::string name;
   if (cert_handle->nickname) {
     name = cert_handle->nickname;
@@ -111,10 +117,9 @@
 
 namespace x509_certificate_model {
 
-using net::X509Certificate;
 using std::string;
 
-string GetCertNameOrNickname(X509Certificate::OSCertHandle cert_handle) {
+string GetCertNameOrNickname(CERTCertificate* cert_handle) {
   string name = ProcessIDN(
       Stringize(CERT_GetCommonName(&cert_handle->subject), std::string()));
   if (!name.empty())
@@ -122,11 +127,11 @@
   return GetNickname(cert_handle);
 }
 
-string GetTokenName(X509Certificate::OSCertHandle cert_handle) {
+string GetTokenName(CERTCertificate* cert_handle) {
   return psm::GetCertTokenName(cert_handle);
 }
 
-string GetVersion(X509Certificate::OSCertHandle cert_handle) {
+string GetVersion(CERTCertificate* cert_handle) {
   // If the version field is omitted from the certificate, the default
   // value is v1(0).
   unsigned long version = 0;
@@ -137,54 +142,55 @@
   return std::string();
 }
 
-net::CertType GetType(X509Certificate::OSCertHandle cert_handle) {
-    return psm::GetCertType(cert_handle);
+net::CertType GetType(CERTCertificate* cert_handle) {
+  return psm::GetCertType(cert_handle);
 }
 
-void GetUsageStrings(X509Certificate::OSCertHandle cert_handle,
+void GetUsageStrings(CERTCertificate* cert_handle,
                      std::vector<string>* usages) {
   psm::GetCertUsageStrings(cert_handle, usages);
 }
 
-string GetSerialNumberHexified(X509Certificate::OSCertHandle cert_handle,
+string GetSerialNumberHexified(CERTCertificate* cert_handle,
                                const string& alternative_text) {
   return Stringize(CERT_Hexify(&cert_handle->serialNumber, true),
                    alternative_text);
 }
 
-string GetIssuerCommonName(X509Certificate::OSCertHandle cert_handle,
+string GetIssuerCommonName(CERTCertificate* cert_handle,
                            const string& alternative_text) {
   return Stringize(CERT_GetCommonName(&cert_handle->issuer), alternative_text);
 }
 
-string GetIssuerOrgName(X509Certificate::OSCertHandle cert_handle,
+string GetIssuerOrgName(CERTCertificate* cert_handle,
                         const string& alternative_text) {
   return Stringize(CERT_GetOrgName(&cert_handle->issuer), alternative_text);
 }
 
-string GetIssuerOrgUnitName(X509Certificate::OSCertHandle cert_handle,
+string GetIssuerOrgUnitName(CERTCertificate* cert_handle,
                             const string& alternative_text) {
   return Stringize(CERT_GetOrgUnitName(&cert_handle->issuer), alternative_text);
 }
 
-string GetSubjectOrgName(X509Certificate::OSCertHandle cert_handle,
+string GetSubjectOrgName(CERTCertificate* cert_handle,
                          const string& alternative_text) {
   return Stringize(CERT_GetOrgName(&cert_handle->subject), alternative_text);
 }
 
-string GetSubjectOrgUnitName(X509Certificate::OSCertHandle cert_handle,
+string GetSubjectOrgUnitName(CERTCertificate* cert_handle,
                              const string& alternative_text) {
   return Stringize(CERT_GetOrgUnitName(&cert_handle->subject),
                    alternative_text);
 }
 
-string GetSubjectCommonName(X509Certificate::OSCertHandle cert_handle,
+string GetSubjectCommonName(CERTCertificate* cert_handle,
                             const string& alternative_text) {
   return Stringize(CERT_GetCommonName(&cert_handle->subject), alternative_text);
 }
 
-bool GetTimes(X509Certificate::OSCertHandle cert_handle,
-              base::Time* issued, base::Time* expires) {
+bool GetTimes(CERTCertificate* cert_handle,
+              base::Time* issued,
+              base::Time* expires) {
   PRTime pr_issued, pr_expires;
   if (CERT_GetCertTimes(cert_handle, &pr_issued, &pr_expires) == SECSuccess) {
     *issued = crypto::PRTimeToBaseTime(pr_issued);
@@ -194,23 +200,30 @@
   return false;
 }
 
-string GetTitle(X509Certificate::OSCertHandle cert_handle) {
+string GetTitle(CERTCertificate* cert_handle) {
   return psm::GetCertTitle(cert_handle);
 }
 
-string GetIssuerName(X509Certificate::OSCertHandle cert_handle) {
+string GetIssuerName(CERTCertificate* cert_handle) {
   return psm::ProcessName(&cert_handle->issuer);
 }
 
-string GetSubjectName(X509Certificate::OSCertHandle cert_handle) {
+string GetSubjectName(CERTCertificate* cert_handle) {
   return psm::ProcessName(&cert_handle->subject);
 }
 
-void GetExtensions(
-    const string& critical_label,
-    const string& non_critical_label,
-    X509Certificate::OSCertHandle cert_handle,
-    Extensions* extensions) {
+std::string GetIssuerDisplayName(CERTCertificate* cert_handle) {
+  return net::x509_util::GetCERTNameDisplayName(&cert_handle->issuer);
+}
+
+std::string GetSubjectDisplayName(CERTCertificate* cert_handle) {
+  return net::x509_util::GetCERTNameDisplayName(&cert_handle->subject);
+}
+
+void GetExtensions(const string& critical_label,
+                   const string& non_critical_label,
+                   CERTCertificate* cert_handle,
+                   Extensions* extensions) {
   if (cert_handle->extensions) {
     for (size_t i = 0; cert_handle->extensions[i] != NULL; ++i) {
       Extension extension;
@@ -222,16 +235,17 @@
   }
 }
 
-string HashCertSHA256(X509Certificate::OSCertHandle cert_handle) {
+string HashCertSHA256(CERTCertificate* cert_handle) {
   return HashCert(cert_handle, HASH_AlgSHA256, SHA256_LENGTH);
 }
 
-string HashCertSHA1(X509Certificate::OSCertHandle cert_handle) {
+string HashCertSHA1(CERTCertificate* cert_handle) {
   return HashCert(cert_handle, HASH_AlgSHA1, SHA1_LENGTH);
 }
 
-string GetCMSString(const X509Certificate::OSCertHandles& cert_chain,
-                    size_t start, size_t end) {
+string GetCMSString(const std::vector<CERTCertificate*>& cert_chain,
+                    size_t start,
+                    size_t end) {
   crypto::ScopedPLArenaPool arena(PORT_NewArena(1024));
   DCHECK(arena.get());
 
@@ -281,29 +295,81 @@
   return string(reinterpret_cast<const char*>(cert_p7.data), cert_p7.len);
 }
 
-string ProcessSecAlgorithmSignature(X509Certificate::OSCertHandle cert_handle) {
+string ProcessSecAlgorithmSignature(CERTCertificate* cert_handle) {
   return ProcessSecAlgorithmInternal(&cert_handle->signature);
 }
 
-string ProcessSecAlgorithmSubjectPublicKey(
-    X509Certificate::OSCertHandle cert_handle) {
+string ProcessSecAlgorithmSubjectPublicKey(CERTCertificate* cert_handle) {
   return ProcessSecAlgorithmInternal(
       &cert_handle->subjectPublicKeyInfo.algorithm);
 }
 
-string ProcessSecAlgorithmSignatureWrap(
-    X509Certificate::OSCertHandle cert_handle) {
+string ProcessSecAlgorithmSignatureWrap(CERTCertificate* cert_handle) {
   return ProcessSecAlgorithmInternal(
       &cert_handle->signatureWrap.signatureAlgorithm);
 }
 
-string ProcessSubjectPublicKeyInfo(X509Certificate::OSCertHandle cert_handle) {
+string ProcessSubjectPublicKeyInfo(CERTCertificate* cert_handle) {
   return psm::ProcessSubjectPublicKeyInfo(&cert_handle->subjectPublicKeyInfo);
 }
 
-string ProcessRawBitsSignatureWrap(X509Certificate::OSCertHandle cert_handle) {
+string ProcessRawBitsSignatureWrap(CERTCertificate* cert_handle) {
   return ProcessRawBits(cert_handle->signatureWrap.signature.data,
                         cert_handle->signatureWrap.signature.len);
 }
 
+std::string ProcessIDN(const std::string& input) {
+  // Convert the ASCII input to a string16 for ICU.
+  base::string16 input16;
+  input16.reserve(input.length());
+  input16.insert(input16.end(), input.begin(), input.end());
+
+  base::string16 output16 = url_formatter::IDNToUnicode(input);
+  if (input16 == output16)
+    return input;  // Input did not contain any encoded data.
+
+  // Input contained encoded data, return formatted string showing original and
+  // decoded forms.
+  return l10n_util::GetStringFUTF8(IDS_CERT_INFO_IDN_VALUE_FORMAT, input16,
+                                   output16);
+}
+
+std::string ProcessRawBytesWithSeparators(const unsigned char* data,
+                                          size_t data_length,
+                                          char hex_separator,
+                                          char line_separator) {
+  static const char kHexChars[] = "0123456789ABCDEF";
+
+  // Each input byte creates two output hex characters + a space or newline,
+  // except for the last byte.
+  std::string ret;
+  size_t kMin = 0U;
+
+  if (!data_length)
+    return std::string();
+
+  ret.reserve(std::max(kMin, data_length * 3 - 1));
+
+  for (size_t i = 0; i < data_length; ++i) {
+    unsigned char b = data[i];
+    ret.push_back(kHexChars[(b >> 4) & 0xf]);
+    ret.push_back(kHexChars[b & 0xf]);
+    if (i + 1 < data_length) {
+      if ((i + 1) % 16 == 0)
+        ret.push_back(line_separator);
+      else
+        ret.push_back(hex_separator);
+    }
+  }
+  return ret;
+}
+
+std::string ProcessRawBytes(const unsigned char* data, size_t data_length) {
+  return ProcessRawBytesWithSeparators(data, data_length, ' ', '\n');
+}
+
+std::string ProcessRawBits(const unsigned char* data, size_t data_length) {
+  return ProcessRawBytes(data, (data_length + 7) / 8);
+}
+
 }  // namespace x509_certificate_model
diff --git a/chrome/common/net/x509_certificate_model_nss.h b/chrome/common/net/x509_certificate_model_nss.h
new file mode 100644
index 0000000..80a1905f
--- /dev/null
+++ b/chrome/common/net/x509_certificate_model_nss.h
@@ -0,0 +1,119 @@
+// Copyright (c) 2011 The Chromium 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 CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_NSS_H_
+#define CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_NSS_H_
+
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+
+#include "net/cert/cert_type.h"
+#include "net/cert/scoped_nss_types.h"
+
+typedef struct CERTCertificateStr CERTCertificate;
+
+namespace base {
+class Time;
+}
+
+// This namespace defines a set of functions to be used in UI-related bits of
+// X509 certificates.
+namespace x509_certificate_model {
+
+std::string GetCertNameOrNickname(CERTCertificate* cert_handle);
+
+std::string GetTokenName(CERTCertificate* cert_handle);
+
+std::string GetVersion(CERTCertificate* cert_handle);
+
+net::CertType GetType(CERTCertificate* cert_handle);
+
+void GetUsageStrings(CERTCertificate* cert_handle,
+                     std::vector<std::string>* usages);
+
+std::string GetSerialNumberHexified(CERTCertificate* cert_handle,
+                                    const std::string& alternative_text);
+
+std::string GetIssuerCommonName(CERTCertificate* cert_handle,
+                                const std::string& alternative_text);
+
+std::string GetIssuerOrgName(CERTCertificate* cert_handle,
+                             const std::string& alternative_text);
+
+std::string GetIssuerOrgUnitName(CERTCertificate* cert_handle,
+                                 const std::string& alternative_text);
+
+std::string GetSubjectOrgName(CERTCertificate* cert_handle,
+                              const std::string& alternative_text);
+
+std::string GetSubjectOrgUnitName(CERTCertificate* cert_handle,
+                                  const std::string& alternative_text);
+
+std::string GetSubjectCommonName(CERTCertificate* cert_handle,
+                                 const std::string& alternative_text);
+
+std::string GetIssuerDisplayName(CERTCertificate* cert_handle);
+std::string GetSubjectDisplayName(CERTCertificate* cert_handle);
+
+bool GetTimes(CERTCertificate* cert_handle,
+              base::Time* issued,
+              base::Time* expires);
+
+std::string GetTitle(CERTCertificate* cert_handle);
+std::string GetIssuerName(CERTCertificate* cert_handle);
+std::string GetSubjectName(CERTCertificate* cert_handle);
+
+struct Extension {
+  std::string name;
+  std::string value;
+};
+
+typedef std::vector<Extension> Extensions;
+
+void GetExtensions(const std::string& critical_label,
+                   const std::string& non_critical_label,
+                   CERTCertificate* cert_handle,
+                   Extensions* extensions);
+
+// Hash a certificate using the given algorithm, return the result as a
+// colon-seperated hex string.
+std::string HashCertSHA256(CERTCertificate* cert_handle);
+std::string HashCertSHA1(CERTCertificate* cert_handle);
+
+std::string GetCMSString(const std::vector<CERTCertificate*>& cert_chain,
+                         size_t start,
+                         size_t end);
+
+std::string ProcessSecAlgorithmSignature(CERTCertificate* cert_handle);
+std::string ProcessSecAlgorithmSubjectPublicKey(CERTCertificate* cert_handle);
+std::string ProcessSecAlgorithmSignatureWrap(CERTCertificate* cert_handle);
+
+std::string ProcessSubjectPublicKeyInfo(CERTCertificate* cert_handle);
+
+std::string ProcessRawBitsSignatureWrap(CERTCertificate* cert_handle);
+
+// For host values, if they contain IDN Punycode-encoded A-labels, this will
+// return a string suitable for display that contains both the original and the
+// decoded U-label form.  Otherwise, the string will be returned as is.
+std::string ProcessIDN(const std::string& input);
+
+// Format a buffer as |hex_separator| separated string, with 16 bytes on each
+// line separated using |line_separator|.
+std::string ProcessRawBytesWithSeparators(const unsigned char* data,
+                                          size_t data_length,
+                                          char hex_separator,
+                                          char line_separator);
+
+// Format a buffer as a space separated string, with 16 bytes on each line.
+std::string ProcessRawBytes(const unsigned char* data, size_t data_length);
+
+// Format a buffer as a space separated string, with 16 bytes on each line.
+// |data_length| is the length in bits.
+std::string ProcessRawBits(const unsigned char* data, size_t data_length);
+
+}  // namespace x509_certificate_model
+
+#endif  // CHROME_COMMON_NET_X509_CERTIFICATE_MODEL_NSS_H_
diff --git a/chrome/common/net/x509_certificate_model_unittest.cc b/chrome/common/net/x509_certificate_model_nss_unittest.cc
similarity index 65%
rename from chrome/common/net/x509_certificate_model_unittest.cc
rename to chrome/common/net/x509_certificate_model_nss_unittest.cc
index 450844d..db36323 100644
--- a/chrome/common/net/x509_certificate_model_unittest.cc
+++ b/chrome/common/net/x509_certificate_model_nss_unittest.cc
@@ -2,70 +2,61 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/common/net/x509_certificate_model.h"
+#include "chrome/common/net/x509_certificate_model_nss.h"
 
 #include <stddef.h>
 
 #include "base/files/file_path.h"
+#include "crypto/scoped_test_nss_db.h"
+#include "net/cert/nss_cert_database.h"
+#include "net/cert/scoped_nss_types.h"
+#include "net/cert/x509_util_nss.h"
 #include "net/test/cert_test_util.h"
 #include "net/test/test_data_directory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if defined(USE_NSS_CERTS)
-#include "crypto/scoped_test_nss_db.h"
-#include "net/cert/nss_cert_database.h"
-#endif
-
 TEST(X509CertificateModelTest, GetCertNameOrNicknameAndGetTitle) {
-  scoped_refptr<net::X509Certificate> cert(
-      net::ImportCertFromFile(net::GetTestCertsDirectory(),
-                              "root_ca_cert.pem"));
+  net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
+      net::GetTestCertsDirectory(), "root_ca_cert.pem"));
   ASSERT_TRUE(cert.get());
-  EXPECT_EQ(
-      "Test Root CA",
-      x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle()));
+  EXPECT_EQ("Test Root CA",
+            x509_certificate_model::GetCertNameOrNickname(cert.get()));
 
-  scoped_refptr<net::X509Certificate> punycode_cert(
-      net::ImportCertFromFile(net::GetTestCertsDirectory(),
-                              "punycodetest.pem"));
+  net::ScopedCERTCertificate punycode_cert(net::ImportCERTCertificateFromFile(
+      net::GetTestCertsDirectory(), "punycodetest.pem"));
   ASSERT_TRUE(punycode_cert.get());
   EXPECT_EQ("xn--wgv71a119e.com (日本語.com)",
-            x509_certificate_model::GetCertNameOrNickname(
-                punycode_cert->os_cert_handle()));
+            x509_certificate_model::GetCertNameOrNickname(punycode_cert.get()));
 
-  scoped_refptr<net::X509Certificate> no_cn_cert(
-      net::ImportCertFromFile(net::GetTestCertsDirectory(),
-                              "no_subject_common_name_cert.pem"));
+  net::ScopedCERTCertificate no_cn_cert(net::ImportCERTCertificateFromFile(
+      net::GetTestCertsDirectory(), "no_subject_common_name_cert.pem"));
   ASSERT_TRUE(no_cn_cert.get());
   // Temp cert has no nickname.
   EXPECT_EQ("",
-            x509_certificate_model::GetCertNameOrNickname(
-                no_cn_cert->os_cert_handle()));
+            x509_certificate_model::GetCertNameOrNickname(no_cn_cert.get()));
 
   EXPECT_EQ("xn--wgv71a119e.com",
-            x509_certificate_model::GetTitle(
-                punycode_cert->os_cert_handle()));
+            x509_certificate_model::GetTitle(punycode_cert.get()));
 
   EXPECT_EQ("[email protected]",
-            x509_certificate_model::GetTitle(
-                no_cn_cert->os_cert_handle()));
+            x509_certificate_model::GetTitle(no_cn_cert.get()));
 
-  scoped_refptr<net::X509Certificate> no_cn_cert2(net::ImportCertFromFile(
+  net::ScopedCERTCertificate no_cn_cert2(net::ImportCERTCertificateFromFile(
       net::GetTestCertsDirectory(), "ct-test-embedded-cert.pem"));
   ASSERT_TRUE(no_cn_cert2.get());
   EXPECT_EQ("L=Erw Wen,ST=Wales,O=Certificate Transparency,C=GB",
-            x509_certificate_model::GetTitle(no_cn_cert2->os_cert_handle()));
+            x509_certificate_model::GetTitle(no_cn_cert2.get()));
 }
 
 TEST(X509CertificateModelTest, GetExtensions) {
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "root_ca_cert.pem"));
     ASSERT_TRUE(cert.get());
 
     x509_certificate_model::Extensions extensions;
-    x509_certificate_model::GetExtensions(
-        "critical", "notcrit", cert->os_cert_handle(), &extensions);
+    x509_certificate_model::GetExtensions("critical", "notcrit", cert.get(),
+                                          &extensions);
     ASSERT_EQ(3U, extensions.size());
 
     EXPECT_EQ("Certificate Basic Constraints", extensions[0].name);
@@ -85,13 +76,13 @@
   }
 
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "subjectAltName_sanity_check.pem"));
     ASSERT_TRUE(cert.get());
 
     x509_certificate_model::Extensions extensions;
-    x509_certificate_model::GetExtensions(
-        "critical", "notcrit", cert->os_cert_handle(), &extensions);
+    x509_certificate_model::GetExtensions("critical", "notcrit", cert.get(),
+                                          &extensions);
     ASSERT_EQ(2U, extensions.size());
     EXPECT_EQ("Certificate Subject Alternative Name", extensions[1].name);
     EXPECT_EQ(
@@ -102,26 +93,26 @@
   }
 
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "foaf.me.chromium-test-cert.der"));
     ASSERT_TRUE(cert.get());
 
     x509_certificate_model::Extensions extensions;
-    x509_certificate_model::GetExtensions(
-        "critical", "notcrit", cert->os_cert_handle(), &extensions);
+    x509_certificate_model::GetExtensions("critical", "notcrit", cert.get(),
+                                          &extensions);
     ASSERT_EQ(5U, extensions.size());
     EXPECT_EQ("Netscape Certificate Comment", extensions[1].name);
     EXPECT_EQ("notcrit\nOpenSSL Generated Certificate", extensions[1].value);
   }
 
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "2029_globalsign_com_cert.pem"));
     ASSERT_TRUE(cert.get());
 
     x509_certificate_model::Extensions extensions;
-    x509_certificate_model::GetExtensions(
-        "critical", "notcrit", cert->os_cert_handle(), &extensions);
+    x509_certificate_model::GetExtensions("critical", "notcrit", cert.get(),
+                                          &extensions);
     ASSERT_EQ(9U, extensions.size());
 
     EXPECT_EQ("Certificate Subject Key ID", extensions[0].name);
@@ -175,13 +166,13 @@
   }
 
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "diginotar_public_ca_2025.pem"));
     ASSERT_TRUE(cert.get());
 
     x509_certificate_model::Extensions extensions;
-    x509_certificate_model::GetExtensions(
-        "critical", "notcrit", cert->os_cert_handle(), &extensions);
+    x509_certificate_model::GetExtensions("critical", "notcrit", cert.get(),
+                                          &extensions);
     ASSERT_EQ(7U, extensions.size());
 
     EXPECT_EQ("Authority Information Access", extensions[0].name);
@@ -208,13 +199,11 @@
 }
 
 TEST(X509CertificateModelTest, GetTypeCA) {
-  scoped_refptr<net::X509Certificate> cert(
-      net::ImportCertFromFile(net::GetTestCertsDirectory(),
-                              "root_ca_cert.pem"));
+  net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
+      net::GetTestCertsDirectory(), "root_ca_cert.pem"));
   ASSERT_TRUE(cert.get());
 
-  EXPECT_EQ(net::CA_CERT,
-            x509_certificate_model::GetType(cert->os_cert_handle()));
+  EXPECT_EQ(net::CA_CERT, x509_certificate_model::GetType(cert.get()));
 
   crypto::ScopedTestNSSDB test_nssdb;
   net::NSSCertDatabase db(crypto::ScopedPK11Slot(PK11_ReferenceSlot(
@@ -224,25 +213,22 @@
 
   // Test that explicitly distrusted CA certs are still returned as CA_CERT
   // type. See http://crbug.com/96654.
-  EXPECT_TRUE(db.SetCertTrust(
-      cert.get(), net::CA_CERT, net::NSSCertDatabase::DISTRUSTED_SSL));
+  EXPECT_TRUE(db.SetCertTrust(cert.get(), net::CA_CERT,
+                              net::NSSCertDatabase::DISTRUSTED_SSL));
 
-  EXPECT_EQ(net::CA_CERT,
-            x509_certificate_model::GetType(cert->os_cert_handle()));
+  EXPECT_EQ(net::CA_CERT, x509_certificate_model::GetType(cert.get()));
 }
 
 TEST(X509CertificateModelTest, GetTypeServer) {
-  scoped_refptr<net::X509Certificate> cert(
-      net::ImportCertFromFile(net::GetTestCertsDirectory(),
-                              "google.single.der"));
+  net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
+      net::GetTestCertsDirectory(), "google.single.der"));
   ASSERT_TRUE(cert.get());
 
   // Test mozilla_security_manager::GetCertType with server certs and default
   // trust.  Currently this doesn't work.
   // TODO(mattm): make mozilla_security_manager::GetCertType smarter so we can
   // tell server certs even if they have no trust bits set.
-  EXPECT_EQ(net::OTHER_CERT,
-            x509_certificate_model::GetType(cert->os_cert_handle()));
+  EXPECT_EQ(net::OTHER_CERT, x509_certificate_model::GetType(cert.get()));
 
   crypto::ScopedTestNSSDB test_nssdb;
   net::NSSCertDatabase db(crypto::ScopedPK11Slot(PK11_ReferenceSlot(
@@ -251,115 +237,108 @@
                               test_nssdb.slot())) /* private slot */);
 
   // Test GetCertType with server certs and explicit trust.
-  EXPECT_TRUE(db.SetCertTrust(
-      cert.get(), net::SERVER_CERT, net::NSSCertDatabase::TRUSTED_SSL));
+  EXPECT_TRUE(db.SetCertTrust(cert.get(), net::SERVER_CERT,
+                              net::NSSCertDatabase::TRUSTED_SSL));
 
-  EXPECT_EQ(net::SERVER_CERT,
-            x509_certificate_model::GetType(cert->os_cert_handle()));
+  EXPECT_EQ(net::SERVER_CERT, x509_certificate_model::GetType(cert.get()));
 
   // Test GetCertType with server certs and explicit distrust.
-  EXPECT_TRUE(db.SetCertTrust(
-      cert.get(), net::SERVER_CERT, net::NSSCertDatabase::DISTRUSTED_SSL));
+  EXPECT_TRUE(db.SetCertTrust(cert.get(), net::SERVER_CERT,
+                              net::NSSCertDatabase::DISTRUSTED_SSL));
 
-  EXPECT_EQ(net::SERVER_CERT,
-            x509_certificate_model::GetType(cert->os_cert_handle()));
+  EXPECT_EQ(net::SERVER_CERT, x509_certificate_model::GetType(cert.get()));
 }
 
 // An X.509 v1 certificate with the version field omitted should get
 // the default value v1.
 TEST(X509CertificateModelTest, GetVersionOmitted) {
-  scoped_refptr<net::X509Certificate> cert(
-      net::ImportCertFromFile(net::GetTestCertsDirectory(),
-                              "ndn.ca.crt"));
+  net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
+      net::GetTestCertsDirectory(), "ndn.ca.crt"));
   ASSERT_TRUE(cert.get());
 
-  EXPECT_EQ("1", x509_certificate_model::GetVersion(cert->os_cert_handle()));
+  EXPECT_EQ("1", x509_certificate_model::GetVersion(cert.get()));
 }
 
 TEST(X509CertificateModelTest, GetCMSString) {
-  net::CertificateList certs =
-      CreateCertificateListFromFile(net::GetTestCertsDirectory(),
-                                    "multi-root-chain1.pem",
-                                    net::X509Certificate::FORMAT_AUTO);
-
-  net::X509Certificate::OSCertHandles cert_handles;
-  for (net::CertificateList::iterator i = certs.begin(); i != certs.end(); ++i)
-    cert_handles.push_back((*i)->os_cert_handle());
-  ASSERT_EQ(4U, cert_handles.size());
+  net::ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
+      net::GetTestCertsDirectory(), "multi-root-chain1.pem",
+      net::X509Certificate::FORMAT_AUTO);
+  std::vector<CERTCertificate*> certs_raw;
+  for (const auto& cert : certs)
+    certs_raw.push_back(cert.get());
 
   {
     // Write the full chain.
-    std::string pkcs7_string = x509_certificate_model::GetCMSString(
-        cert_handles, 0, cert_handles.size());
+    std::string pkcs7_string =
+        x509_certificate_model::GetCMSString(certs_raw, 0, certs_raw.size());
 
     ASSERT_FALSE(pkcs7_string.empty());
 
-    net::CertificateList decoded_certs =
-        net::X509Certificate::CreateCertificateListFromBytes(
-            pkcs7_string.data(),
-            pkcs7_string.size(),
+    net::ScopedCERTCertificateList decoded_certs =
+        net::x509_util::CreateCERTCertificateListFromBytes(
+            pkcs7_string.data(), pkcs7_string.size(),
             net::X509Certificate::FORMAT_PKCS7);
 
     ASSERT_EQ(certs.size(), decoded_certs.size());
 
     // NSS sorts the certs before writing the file.
-    EXPECT_TRUE(certs[0]->Equals(decoded_certs.back().get()));
+    EXPECT_TRUE(net::x509_util::IsSameCertificate(certs[0].get(),
+                                                  decoded_certs.back().get()));
     for (size_t i = 1; i < certs.size(); ++i)
-      EXPECT_TRUE(certs[i]->Equals(decoded_certs[i - 1].get()));
+      EXPECT_TRUE(net::x509_util::IsSameCertificate(
+          certs[i].get(), decoded_certs[i - 1].get()));
   }
 
   {
     // Write only the first cert.
     std::string pkcs7_string =
-        x509_certificate_model::GetCMSString(cert_handles, 0, 1);
+        x509_certificate_model::GetCMSString(certs_raw, 0, 1);
 
-    net::CertificateList decoded_certs =
-        net::X509Certificate::CreateCertificateListFromBytes(
-            pkcs7_string.data(),
-            pkcs7_string.size(),
+    net::ScopedCERTCertificateList decoded_certs =
+        net::x509_util::CreateCERTCertificateListFromBytes(
+            pkcs7_string.data(), pkcs7_string.size(),
             net::X509Certificate::FORMAT_PKCS7);
 
     ASSERT_EQ(1U, decoded_certs.size());
-    EXPECT_TRUE(certs[0]->Equals(decoded_certs[0].get()));
+    EXPECT_TRUE(net::x509_util::IsSameCertificate(certs[0].get(),
+                                                  decoded_certs[0].get()));
   }
 }
 
 TEST(X509CertificateModelTest, ProcessSecAlgorithms) {
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "root_ca_cert.pem"));
     ASSERT_TRUE(cert.get());
 
     EXPECT_EQ("PKCS #1 SHA-256 With RSA Encryption",
-              x509_certificate_model::ProcessSecAlgorithmSignature(
-                  cert->os_cert_handle()));
-    EXPECT_EQ("PKCS #1 SHA-256 With RSA Encryption",
-              x509_certificate_model::ProcessSecAlgorithmSignatureWrap(
-                  cert->os_cert_handle()));
+              x509_certificate_model::ProcessSecAlgorithmSignature(cert.get()));
+    EXPECT_EQ(
+        "PKCS #1 SHA-256 With RSA Encryption",
+        x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert.get()));
     EXPECT_EQ("PKCS #1 RSA Encryption",
               x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(
-                  cert->os_cert_handle()));
+                  cert.get()));
   }
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "weak_digest_md5_root.pem"));
     ASSERT_TRUE(cert.get());
 
     EXPECT_EQ("PKCS #1 MD5 With RSA Encryption",
-              x509_certificate_model::ProcessSecAlgorithmSignature(
-                  cert->os_cert_handle()));
-    EXPECT_EQ("PKCS #1 MD5 With RSA Encryption",
-              x509_certificate_model::ProcessSecAlgorithmSignatureWrap(
-                  cert->os_cert_handle()));
+              x509_certificate_model::ProcessSecAlgorithmSignature(cert.get()));
+    EXPECT_EQ(
+        "PKCS #1 MD5 With RSA Encryption",
+        x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert.get()));
     EXPECT_EQ("PKCS #1 RSA Encryption",
               x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(
-                  cert->os_cert_handle()));
+                  cert.get()));
   }
 }
 
 TEST(X509CertificateModelTest, ProcessSubjectPublicKeyInfo) {
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "root_ca_cert.pem"));
     ASSERT_TRUE(cert.get());
 
@@ -384,11 +363,10 @@
         "\n"
         "  Public Exponent (24 bits):\n"
         "  01 00 01",
-        x509_certificate_model::ProcessSubjectPublicKeyInfo(
-            cert->os_cert_handle()));
+        x509_certificate_model::ProcessSubjectPublicKeyInfo(cert.get()));
   }
   {
-    scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+    net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
         net::GetTestCertsDirectory(), "prime256v1-ecdsa-intermediate.pem"));
     ASSERT_TRUE(cert.get());
 
@@ -398,13 +376,12 @@
         "2D EA 30 0F D2 9A 47 97 2C 7E 89 E6 EF 49 55 06\n"
         "C9 37 C7 99 56 16 B2 2B C9 7C 69 8E 10 7A DD 1F\n"
         "42",
-        x509_certificate_model::ProcessSubjectPublicKeyInfo(
-            cert->os_cert_handle()));
+        x509_certificate_model::ProcessSubjectPublicKeyInfo(cert.get()));
   }
 }
 
 TEST(X509CertificateModelTest, ProcessRawBitsSignatureWrap) {
-  scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
+  net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
       net::GetTestCertsDirectory(), "root_ca_cert.pem"));
   ASSERT_TRUE(cert.get());
 
@@ -425,6 +402,5 @@
       "69 17 79 02 3A EC 1D 6F 5E BB 13 FB A6 82 5D 07\n"
       "20 FC 86 FE 6E 8B AC E1 C2 18 A2 FE 3F 95 66 D3\n"
       "69 8A 00 06 2C 56 37 34 B9 B6 31 DE 0F F6 44 39",
-      x509_certificate_model::ProcessRawBitsSignatureWrap(
-          cert->os_cert_handle()));
+      x509_certificate_model::ProcessRawBitsSignatureWrap(cert.get()));
 }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index c83f248c..2de69a0 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4961,7 +4961,7 @@
     }
   }
   if (!is_android && use_nss_certs) {
-    sources += [ "../common/net/x509_certificate_model_unittest.cc" ]
+    sources += [ "../common/net/x509_certificate_model_nss_unittest.cc" ]
   }
   if (enable_supervised_users) {
     sources += [
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
index 2481f7b..6e5d5b54 100644
--- a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
@@ -52,7 +52,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/common/net/x509_certificate_model.h"
+#include "chrome/common/net/x509_certificate_model_nss.h"
 #include "chrome/grit/generated_resources.h"
 #include "crypto/scoped_nss_types.h"
 #include "net/base/ip_address.h"
diff --git a/net/cert/nss_cert_database.cc b/net/cert/nss_cert_database.cc
index 2b90e00..4f05316 100644
--- a/net/cert/nss_cert_database.cc
+++ b/net/cert/nss_cert_database.cc
@@ -356,9 +356,9 @@
   return false;
 }
 
-bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert,
-                                CertType type,
-                                TrustBits trust_bits) {
+bool NSSCertDatabase::SetCertTrust(CERTCertificate* cert,
+                                   CertType type,
+                                   TrustBits trust_bits) {
   bool success = psm::SetCertTrust(cert, type, trust_bits);
   if (success)
     NotifyObserversCertDBChanged();
@@ -366,6 +366,12 @@
   return success;
 }
 
+bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert,
+                                   CertType type,
+                                   TrustBits trust_bits) {
+  return SetCertTrust(cert->os_cert_handle(), type, trust_bits);
+}
+
 bool NSSCertDatabase::DeleteCertAndKey(X509Certificate* cert) {
   if (!DeleteCertAndKeyImpl(cert))
     return false;
diff --git a/net/cert/nss_cert_database.h b/net/cert/nss_cert_database.h
index 27b06aa..5b068735 100644
--- a/net/cert/nss_cert_database.h
+++ b/net/cert/nss_cert_database.h
@@ -33,6 +33,10 @@
 // Provides functions to manipulate the NSS certificate stores.
 // Forwards notifications about certificate changes to the global CertDatabase
 // singleton.
+//
+// TODO(mattm): some methods have overloads to take either X509Certificate or
+// native NSS types. This is a temporary situation while crbug.com/671420 is in
+// progress. Once 671420 is done, this class will only use NSS native types.
 class NET_EXPORT NSSCertDatabase {
  public:
   class NET_EXPORT Observer {
@@ -212,6 +216,7 @@
 
   // Set trust values for certificate.
   // Returns true on success or false on failure.
+  bool SetCertTrust(CERTCertificate* cert, CertType type, TrustBits trust_bits);
   bool SetCertTrust(const X509Certificate* cert,
                     CertType type,
                     TrustBits trust_bits);
diff --git a/net/cert/x509_util_nss.cc b/net/cert/x509_util_nss.cc
index c7a9c19..711364b 100644
--- a/net/cert/x509_util_nss.cc
+++ b/net/cert/x509_util_nss.cc
@@ -210,6 +210,23 @@
   return nss_chain;
 }
 
+ScopedCERTCertificateList CreateCERTCertificateListFromBytes(const char* data,
+                                                             size_t length,
+                                                             int format) {
+  CertificateList certs =
+      X509Certificate::CreateCertificateListFromBytes(data, length, format);
+  ScopedCERTCertificateList nss_chain;
+  nss_chain.reserve(certs.size());
+  for (const scoped_refptr<X509Certificate>& cert : certs) {
+    ScopedCERTCertificate nss_cert =
+        CreateCERTCertificateFromX509Certificate(cert.get());
+    if (!nss_cert)
+      return {};
+    nss_chain.push_back(std::move(nss_cert));
+  }
+  return nss_chain;
+}
+
 ScopedCERTCertificate DupCERTCertificate(CERTCertificate* cert) {
   return ScopedCERTCertificate(CERT_DupCertificate(cert));
 }
diff --git a/net/cert/x509_util_nss.h b/net/cert/x509_util_nss.h
index 4f71011..8e05cdc 100644
--- a/net/cert/x509_util_nss.h
+++ b/net/cert/x509_util_nss.h
@@ -46,6 +46,13 @@
 NET_EXPORT ScopedCERTCertificateList
 CreateCERTCertificateListFromX509Certificate(const X509Certificate* cert);
 
+// Parses all of the certificates possible from |data|. |format| is a
+// bit-wise OR of X509Certificate::Format, indicating the possible formats the
+// certificates may have been serialized as. If an error occurs, an empty
+// collection will be returned.
+NET_EXPORT ScopedCERTCertificateList
+CreateCERTCertificateListFromBytes(const char* data, size_t length, int format);
+
 // Increments the refcount of |cert| and returns a handle for that reference.
 NET_EXPORT ScopedCERTCertificate DupCERTCertificate(CERTCertificate* cert);
 
diff --git a/net/cert/x509_util_nss_unittest.cc b/net/cert/x509_util_nss_unittest.cc
index a7e3d0ec..5a2b56e 100644
--- a/net/cert/x509_util_nss_unittest.cc
+++ b/net/cert/x509_util_nss_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/cert/x509_util_nss.h"
 
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "net/cert/scoped_nss_types.h"
 #include "net/cert/x509_certificate.h"
 #include "net/test/cert_test_util.h"
@@ -136,6 +138,23 @@
             BytesForNSSCert(nss_certs[3].get()));
 }
 
+TEST(X509UtilNSSTest, CreateCERTCertificateListFromBytes) {
+  base::FilePath cert_path =
+      GetTestCertsDirectory().AppendASCII("multi-root-chain1.pem");
+  std::string cert_data;
+  ASSERT_TRUE(base::ReadFileToString(cert_path, &cert_data));
+
+  ScopedCERTCertificateList certs =
+      x509_util::CreateCERTCertificateListFromBytes(
+          cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
+  ASSERT_EQ(4U, certs.size());
+  EXPECT_STREQ("CN=127.0.0.1,O=Test CA,L=Mountain View,ST=California,C=US",
+               certs[0]->subjectName);
+  EXPECT_STREQ("CN=B CA - Multi-root", certs[1]->subjectName);
+  EXPECT_STREQ("CN=C CA - Multi-root", certs[2]->subjectName);
+  EXPECT_STREQ("CN=D Root CA - Multi-root", certs[3]->subjectName);
+}
+
 TEST(X509UtilNSSTest, DupCERTCertificate) {
   ScopedCERTCertificate cert(x509_util::CreateCERTCertificateFromBytes(
       google_der, arraysize(google_der)));
diff --git a/net/test/cert_test_util.h b/net/test/cert_test_util.h
index 1369265..3bc2f87 100644
--- a/net/test/cert_test_util.h
+++ b/net/test/cert_test_util.h
@@ -13,6 +13,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(USE_NSS_CERTS)
+#include "net/cert/scoped_nss_types.h"
+
 // From <pk11pub.h>
 typedef struct PK11SlotInfoStr PK11SlotInfo;
 
@@ -50,6 +52,15 @@
     const std::string& cert_filename,
     const std::string& key_filename,
     PK11SlotInfo* slot);
+
+ScopedCERTCertificate ImportCERTCertificateFromFile(
+    const base::FilePath& certs_dir,
+    const std::string& cert_file);
+
+ScopedCERTCertificateList CreateCERTCertificateListFromFile(
+    const base::FilePath& certs_dir,
+    const std::string& cert_file,
+    int format);
 #endif
 
 // Imports all of the certificates in |cert_file|, a file in |certs_dir|, into a
diff --git a/net/test/cert_test_util_nss.cc b/net/test/cert_test_util_nss.cc
index ac6ba02e..8afd5db1 100644
--- a/net/test/cert_test_util_nss.cc
+++ b/net/test/cert_test_util_nss.cc
@@ -97,4 +97,31 @@
                                         &nss_cert);
 }
 
+ScopedCERTCertificate ImportCERTCertificateFromFile(
+    const base::FilePath& certs_dir,
+    const std::string& cert_file) {
+  scoped_refptr<X509Certificate> cert =
+      ImportCertFromFile(certs_dir, cert_file);
+  if (!cert)
+    return nullptr;
+  return x509_util::CreateCERTCertificateFromX509Certificate(cert.get());
+}
+
+ScopedCERTCertificateList CreateCERTCertificateListFromFile(
+    const base::FilePath& certs_dir,
+    const std::string& cert_file,
+    int format) {
+  CertificateList certs =
+      CreateCertificateListFromFile(certs_dir, cert_file, format);
+  ScopedCERTCertificateList nss_certs;
+  for (const auto& cert : certs) {
+    ScopedCERTCertificate nss_cert =
+        x509_util::CreateCERTCertificateFromX509Certificate(cert.get());
+    if (!nss_cert)
+      return {};
+    nss_certs.push_back(std::move(nss_cert));
+  }
+  return nss_certs;
+}
+
 }  // namespace net
diff --git a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
index c6c47913..1b6e394a 100644
--- a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
+++ b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
@@ -96,7 +96,7 @@
       LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError();
       return false;
     }
-    if (!SetCertTrust(root, net::CA_CERT, trustBits))
+    if (!SetCertTrust(root->os_cert_handle(), net::CA_CERT, trustBits))
       return false;
   }
 
@@ -190,7 +190,7 @@
     }
   }
 
-  SetCertTrust(certificates[0].get(), net::SERVER_CERT, trustBits);
+  SetCertTrust(certificates[0]->os_cert_handle(), net::SERVER_CERT, trustBits);
   // TODO(mattm): Report SetCertTrust result?  Putting in not_imported
   // wouldn't quite match up since it was imported...
 
@@ -229,11 +229,9 @@
 }
 
 // Based on nsNSSCertificateDB::SetCertTrust.
-bool
-SetCertTrust(const net::X509Certificate* cert,
-             net::CertType type,
-             net::NSSCertDatabase::TrustBits trustBits)
-{
+bool SetCertTrust(CERTCertificate* nsscert,
+                  net::CertType type,
+                  net::NSSCertDatabase::TrustBits trustBits) {
   const unsigned kSSLTrustBits = net::NSSCertDatabase::TRUSTED_SSL |
       net::NSSCertDatabase::DISTRUSTED_SSL;
   const unsigned kEmailTrustBits = net::NSSCertDatabase::TRUSTED_EMAIL |
@@ -250,7 +248,6 @@
   }
 
   SECStatus srv;
-  CERTCertificate *nsscert = cert->os_cert_handle();
   if (type == net::CA_CERT) {
     // Note that we start with CERTDB_VALID_CA for default trust and explicit
     // trust, but explicitly distrusted usages will be set to
diff --git a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h
index 285474b..74673ad 100644
--- a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h
+++ b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h
@@ -67,7 +67,7 @@
 
 int ImportUserCert(const net::CertificateList& certificates);
 
-bool SetCertTrust(const net::X509Certificate* cert,
+bool SetCertTrust(CERTCertificate* cert,
                   net::CertType type,
                   net::NSSCertDatabase::TrustBits trustBits);