Index: net/base/cert_database_nss.cc |
=================================================================== |
--- net/base/cert_database_nss.cc (revision 0) |
+++ net/base/cert_database_nss.cc (revision 0) |
@@ -0,0 +1,102 @@ |
+// Copyright (c) 2009 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 "net/base/cert_database.h" |
+ |
+// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 |
+// until NSS 3.12.2 comes out and we update to it. |
+#define Lock FOO_NSS_Lock |
+#include <pk11pub.h> |
+#include <secmod.h> |
+#include <ssl.h> |
+#include <nssb64.h> // NSSBase64_EncodeItem() |
+#include <secder.h> // DER_Encode() |
+#include <cryptohi.h> // SEC_DerSignData() |
+#include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo() |
+#undef Lock |
+ |
+#include "base/logging.h" |
+#include "base/scoped_ptr.h" |
+#include "base/nss_init.h" |
+ |
+namespace net { |
+ |
+CertDatabase::CertDatabase() { |
+ Init(); |
+} |
+ |
+bool CertDatabase::AddUserCert(const char* data, int len) { |
+ CERTCertificate* cert = NULL; |
+ PK11SlotInfo* slot = NULL; |
+ std::string nickname; |
+ bool is_success = true; |
+ |
+ // Make a copy of "data" since CERT_DecodeCertPackage |
+ // might modify it. |
+ char* data_copy = new char[len]; |
+ memcpy(data_copy, data, len); |
+ |
+ // Parse into a certificate structure. |
+ cert = CERT_DecodeCertFromPackage(data_copy, len); |
+ delete [] data_copy; |
+ if (!cert) { |
+ LOG(ERROR) << "Couldn't create a temporary certificate"; |
+ return false; |
+ } |
+ |
+ // Check if the private key corresponding to the certificate exist |
+ // We shouldn't accept any random client certificate sent by a CA. |
+ |
+ // Note: The NSS source documentation wrongly suggests that this |
+ // also imports the certificate if the private key exists. This |
+ // doesn't seem to be the case. |
+ |
+ slot = PK11_KeyForCertExists(cert, NULL, NULL); |
+ if (!slot) { |
+ LOG(ERROR) << "No corresponding private key in store"; |
+ CERT_DestroyCertificate(cert); |
+ return false; |
+ } |
+ PK11_FreeSlot(slot); |
+ slot = NULL; |
+ |
+ // TODO(gauravsh): We also need to make sure another certificate |
+ // doesn't already exist for the same private key. |
+ |
+ // Create a nickname for this certificate. |
+ // We use the scheme used by Firefox: |
+ // --> <subject's common name>'s <issuer's common name> ID. |
+ // |
+ |
+ std::string username, ca_name; |
+ char* temp_username = CERT_GetCommonName(&cert->subject); |
+ char* temp_ca_name = CERT_GetCommonName(&cert->issuer); |
+ if (temp_username) { |
+ username = temp_username; |
+ PORT_Free(temp_username); |
+ } |
+ if (temp_ca_name) { |
+ ca_name = temp_ca_name; |
+ PORT_Free(temp_ca_name); |
+ } |
+ nickname = username + "'s " + ca_name + " ID"; |
+ |
+ slot = PK11_ImportCertForKey(cert, |
+ const_cast<char*>(nickname.c_str()), |
+ NULL); |
+ if (slot) { |
+ PK11_FreeSlot(slot); |
+ } else { |
+ LOG(ERROR) << "Couldn't import user certificate."; |
+ is_success = false; |
+ } |
+ CERT_DestroyCertificate(cert); |
+ return is_success; |
+} |
+ |
+void CertDatabase::Init() { |
+ base::EnsureNSSInit(); |
+} |
+ |
+} // namespace net |
Property changes on: net/base/cert_database_nss.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |