| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert/nss_cert_database.h" | 5 #include "net/cert/nss_cert_database.h" |
| 6 | 6 |
| 7 #include <cert.h> | 7 #include <cert.h> |
| 8 #include <certdb.h> | 8 #include <certdb.h> |
| 9 #include <pk11pub.h> | 9 #include <pk11pub.h> |
| 10 | 10 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 class CertDatabaseNSSTest : public testing::Test { | 62 class CertDatabaseNSSTest : public testing::Test { |
| 63 public: | 63 public: |
| 64 void SetUp() override { | 64 void SetUp() override { |
| 65 ASSERT_TRUE(test_nssdb_.is_open()); | 65 ASSERT_TRUE(test_nssdb_.is_open()); |
| 66 cert_db_.reset(new NSSCertDatabase( | 66 cert_db_.reset(new NSSCertDatabase( |
| 67 crypto::ScopedPK11Slot( | 67 crypto::ScopedPK11Slot( |
| 68 PK11_ReferenceSlot(test_nssdb_.slot())) /* public slot */, | 68 PK11_ReferenceSlot(test_nssdb_.slot())) /* public slot */, |
| 69 crypto::ScopedPK11Slot( | 69 crypto::ScopedPK11Slot( |
| 70 PK11_ReferenceSlot(test_nssdb_.slot())) /* private slot */)); | 70 PK11_ReferenceSlot(test_nssdb_.slot())) /* private slot */)); |
| 71 public_module_ = cert_db_->GetPublicModule(); | 71 public_slot_ = cert_db_->GetPublicSlot(); |
| 72 | 72 |
| 73 // Test db should be empty at start of test. | 73 // Test db should be empty at start of test. |
| 74 EXPECT_EQ(0U, ListCerts().size()); | 74 EXPECT_EQ(0U, ListCerts().size()); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void TearDown() override { | 77 void TearDown() override { |
| 78 // Run the message loop to process any observer callbacks (e.g. for the | 78 // Run the message loop to process any observer callbacks (e.g. for the |
| 79 // ClientSocketFactory singleton) so that the scoped ref ptrs created in | 79 // ClientSocketFactory singleton) so that the scoped ref ptrs created in |
| 80 // NSSCertDatabase::NotifyObservers* get released. | 80 // NSSCertDatabase::NotifyObservers* get released. |
| 81 base::RunLoop().RunUntilIdle(); | 81 base::RunLoop().RunUntilIdle(); |
| 82 } | 82 } |
| 83 | 83 |
| 84 protected: | 84 protected: |
| 85 CryptoModule* GetPublicModule() { return public_module_.get(); } | 85 PK11SlotInfo* GetPublicSlot() { return public_slot_.get(); } |
| 86 | 86 |
| 87 static std::string ReadTestFile(const std::string& name) { | 87 static std::string ReadTestFile(const std::string& name) { |
| 88 std::string result; | 88 std::string result; |
| 89 base::FilePath cert_path = GetTestCertsDirectory().AppendASCII(name); | 89 base::FilePath cert_path = GetTestCertsDirectory().AppendASCII(name); |
| 90 EXPECT_TRUE(base::ReadFileToString(cert_path, &result)); | 90 EXPECT_TRUE(base::ReadFileToString(cert_path, &result)); |
| 91 return result; | 91 return result; |
| 92 } | 92 } |
| 93 | 93 |
| 94 static bool ReadCertIntoList(const std::string& name, | 94 static bool ReadCertIntoList(const std::string& name, |
| 95 CertificateList* certs) { | 95 CertificateList* certs) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 121 return SHA256HashValueLessThan()( | 121 return SHA256HashValueLessThan()( |
| 122 X509Certificate::CalculateFingerprint256(lhs->os_cert_handle()), | 122 X509Certificate::CalculateFingerprint256(lhs->os_cert_handle()), |
| 123 X509Certificate::CalculateFingerprint256(rhs->os_cert_handle())); | 123 X509Certificate::CalculateFingerprint256(rhs->os_cert_handle())); |
| 124 }); | 124 }); |
| 125 return result; | 125 return result; |
| 126 } | 126 } |
| 127 | 127 |
| 128 std::unique_ptr<NSSCertDatabase> cert_db_; | 128 std::unique_ptr<NSSCertDatabase> cert_db_; |
| 129 const CertificateList empty_cert_list_; | 129 const CertificateList empty_cert_list_; |
| 130 crypto::ScopedTestNSSDB test_nssdb_; | 130 crypto::ScopedTestNSSDB test_nssdb_; |
| 131 scoped_refptr<CryptoModule> public_module_; | 131 crypto::ScopedPK11Slot public_slot_; |
| 132 }; | 132 }; |
| 133 | 133 |
| 134 TEST_F(CertDatabaseNSSTest, ListCertsSync) { | 134 TEST_F(CertDatabaseNSSTest, ListCertsSync) { |
| 135 // This test isn't terribly useful, though it will at least let valgrind test | 135 // This test isn't terribly useful, though it will at least let valgrind test |
| 136 // for leaks. | 136 // for leaks. |
| 137 CertificateList certs; | 137 CertificateList certs; |
| 138 cert_db_->ListCertsSync(&certs); | 138 cert_db_->ListCertsSync(&certs); |
| 139 // The test DB is empty, but let's assume there will always be something in | 139 // The test DB is empty, but let's assume there will always be something in |
| 140 // the other slots. | 140 // the other slots. |
| 141 EXPECT_LT(0U, certs.size()); | 141 EXPECT_LT(0U, certs.size()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 153 | 153 |
| 154 // The test DB is empty, but let's assume there will always be something in | 154 // The test DB is empty, but let's assume there will always be something in |
| 155 // the other slots. | 155 // the other slots. |
| 156 EXPECT_LT(0U, certs.size()); | 156 EXPECT_LT(0U, certs.size()); |
| 157 } | 157 } |
| 158 | 158 |
| 159 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) { | 159 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) { |
| 160 std::string pkcs12_data = ReadTestFile("client.p12"); | 160 std::string pkcs12_data = ReadTestFile("client.p12"); |
| 161 | 161 |
| 162 EXPECT_EQ(ERR_PKCS12_IMPORT_BAD_PASSWORD, | 162 EXPECT_EQ(ERR_PKCS12_IMPORT_BAD_PASSWORD, |
| 163 cert_db_->ImportFromPKCS12(GetPublicModule(), | 163 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 164 pkcs12_data, | 164 pkcs12_data, |
| 165 base::string16(), | 165 base::string16(), |
| 166 true, // is_extractable | 166 true, // is_extractable |
| 167 NULL)); | 167 NULL)); |
| 168 | 168 |
| 169 // Test db should still be empty. | 169 // Test db should still be empty. |
| 170 EXPECT_EQ(0U, ListCerts().size()); | 170 EXPECT_EQ(0U, ListCerts().size()); |
| 171 } | 171 } |
| 172 | 172 |
| 173 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) { | 173 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) { |
| 174 std::string pkcs12_data = ReadTestFile("client.p12"); | 174 std::string pkcs12_data = ReadTestFile("client.p12"); |
| 175 | 175 |
| 176 EXPECT_EQ(OK, | 176 EXPECT_EQ(OK, |
| 177 cert_db_->ImportFromPKCS12(GetPublicModule(), | 177 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 178 pkcs12_data, | 178 pkcs12_data, |
| 179 ASCIIToUTF16("12345"), | 179 ASCIIToUTF16("12345"), |
| 180 true, // is_extractable | 180 true, // is_extractable |
| 181 NULL)); | 181 NULL)); |
| 182 | 182 |
| 183 CertificateList cert_list = ListCerts(); | 183 CertificateList cert_list = ListCerts(); |
| 184 ASSERT_EQ(1U, cert_list.size()); | 184 ASSERT_EQ(1U, cert_list.size()); |
| 185 scoped_refptr<X509Certificate> cert(cert_list[0]); | 185 scoped_refptr<X509Certificate> cert(cert_list[0]); |
| 186 | 186 |
| 187 EXPECT_EQ("testusercert", | 187 EXPECT_EQ("testusercert", |
| 188 cert->subject().common_name); | 188 cert->subject().common_name); |
| 189 | 189 |
| 190 // TODO(mattm): move export test to separate test case? | 190 // TODO(mattm): move export test to separate test case? |
| 191 std::string exported_data; | 191 std::string exported_data; |
| 192 EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), | 192 EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), |
| 193 &exported_data)); | 193 &exported_data)); |
| 194 ASSERT_LT(0U, exported_data.size()); | 194 ASSERT_LT(0U, exported_data.size()); |
| 195 // TODO(mattm): further verification of exported data? | 195 // TODO(mattm): further verification of exported data? |
| 196 } | 196 } |
| 197 | 197 |
| 198 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) { | 198 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) { |
| 199 std::string pkcs12_data = ReadTestFile("client.p12"); | 199 std::string pkcs12_data = ReadTestFile("client.p12"); |
| 200 | 200 |
| 201 EXPECT_EQ(OK, | 201 EXPECT_EQ(OK, |
| 202 cert_db_->ImportFromPKCS12(GetPublicModule(), | 202 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 203 pkcs12_data, | 203 pkcs12_data, |
| 204 ASCIIToUTF16("12345"), | 204 ASCIIToUTF16("12345"), |
| 205 true, // is_extractable | 205 true, // is_extractable |
| 206 NULL)); | 206 NULL)); |
| 207 EXPECT_EQ(1U, ListCerts().size()); | 207 EXPECT_EQ(1U, ListCerts().size()); |
| 208 | 208 |
| 209 // NSS has a SEC_ERROR_PKCS12_DUPLICATE_DATA error, but it doesn't look like | 209 // NSS has a SEC_ERROR_PKCS12_DUPLICATE_DATA error, but it doesn't look like |
| 210 // it's ever used. This test verifies that. | 210 // it's ever used. This test verifies that. |
| 211 EXPECT_EQ(OK, | 211 EXPECT_EQ(OK, |
| 212 cert_db_->ImportFromPKCS12(GetPublicModule(), | 212 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 213 pkcs12_data, | 213 pkcs12_data, |
| 214 ASCIIToUTF16("12345"), | 214 ASCIIToUTF16("12345"), |
| 215 true, // is_extractable | 215 true, // is_extractable |
| 216 NULL)); | 216 NULL)); |
| 217 EXPECT_EQ(1U, ListCerts().size()); | 217 EXPECT_EQ(1U, ListCerts().size()); |
| 218 } | 218 } |
| 219 | 219 |
| 220 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) { | 220 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) { |
| 221 std::string pkcs12_data = ReadTestFile("client.p12"); | 221 std::string pkcs12_data = ReadTestFile("client.p12"); |
| 222 | 222 |
| 223 EXPECT_EQ(OK, | 223 EXPECT_EQ(OK, |
| 224 cert_db_->ImportFromPKCS12(GetPublicModule(), | 224 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 225 pkcs12_data, | 225 pkcs12_data, |
| 226 ASCIIToUTF16("12345"), | 226 ASCIIToUTF16("12345"), |
| 227 false, // is_extractable | 227 false, // is_extractable |
| 228 NULL)); | 228 NULL)); |
| 229 | 229 |
| 230 CertificateList cert_list = ListCerts(); | 230 CertificateList cert_list = ListCerts(); |
| 231 ASSERT_EQ(1U, cert_list.size()); | 231 ASSERT_EQ(1U, cert_list.size()); |
| 232 scoped_refptr<X509Certificate> cert(cert_list[0]); | 232 scoped_refptr<X509Certificate> cert(cert_list[0]); |
| 233 | 233 |
| 234 EXPECT_EQ("testusercert", | 234 EXPECT_EQ("testusercert", |
| 235 cert->subject().common_name); | 235 cert->subject().common_name); |
| 236 | 236 |
| 237 std::string exported_data; | 237 std::string exported_data; |
| 238 EXPECT_EQ(0, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), | 238 EXPECT_EQ(0, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), |
| 239 &exported_data)); | 239 &exported_data)); |
| 240 } | 240 } |
| 241 | 241 |
| 242 // Importing a PKCS#12 file with a certificate but no corresponding | 242 // Importing a PKCS#12 file with a certificate but no corresponding |
| 243 // private key should not mark an existing private key as unextractable. | 243 // private key should not mark an existing private key as unextractable. |
| 244 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) { | 244 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) { |
| 245 std::string pkcs12_data = ReadTestFile("client.p12"); | 245 std::string pkcs12_data = ReadTestFile("client.p12"); |
| 246 EXPECT_EQ(OK, | 246 EXPECT_EQ(OK, |
| 247 cert_db_->ImportFromPKCS12(GetPublicModule(), | 247 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 248 pkcs12_data, | 248 pkcs12_data, |
| 249 ASCIIToUTF16("12345"), | 249 ASCIIToUTF16("12345"), |
| 250 true, // is_extractable | 250 true, // is_extractable |
| 251 NULL)); | 251 NULL)); |
| 252 | 252 |
| 253 CertificateList cert_list = ListCerts(); | 253 CertificateList cert_list = ListCerts(); |
| 254 ASSERT_EQ(1U, cert_list.size()); | 254 ASSERT_EQ(1U, cert_list.size()); |
| 255 | 255 |
| 256 // Now import a PKCS#12 file with just a certificate but no private key. | 256 // Now import a PKCS#12 file with just a certificate but no private key. |
| 257 pkcs12_data = ReadTestFile("client-nokey.p12"); | 257 pkcs12_data = ReadTestFile("client-nokey.p12"); |
| 258 EXPECT_EQ(OK, | 258 EXPECT_EQ(OK, |
| 259 cert_db_->ImportFromPKCS12(GetPublicModule(), | 259 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 260 pkcs12_data, | 260 pkcs12_data, |
| 261 ASCIIToUTF16("12345"), | 261 ASCIIToUTF16("12345"), |
| 262 false, // is_extractable | 262 false, // is_extractable |
| 263 NULL)); | 263 NULL)); |
| 264 | 264 |
| 265 cert_list = ListCerts(); | 265 cert_list = ListCerts(); |
| 266 ASSERT_EQ(1U, cert_list.size()); | 266 ASSERT_EQ(1U, cert_list.size()); |
| 267 | 267 |
| 268 // Make sure the imported private key is still extractable. | 268 // Make sure the imported private key is still extractable. |
| 269 std::string exported_data; | 269 std::string exported_data; |
| 270 EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), | 270 EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), |
| 271 &exported_data)); | 271 &exported_data)); |
| 272 ASSERT_LT(0U, exported_data.size()); | 272 ASSERT_LT(0U, exported_data.size()); |
| 273 } | 273 } |
| 274 | 274 |
| 275 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) { | 275 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) { |
| 276 std::string pkcs12_data = "Foobarbaz"; | 276 std::string pkcs12_data = "Foobarbaz"; |
| 277 | 277 |
| 278 EXPECT_EQ(ERR_PKCS12_IMPORT_INVALID_FILE, | 278 EXPECT_EQ(ERR_PKCS12_IMPORT_INVALID_FILE, |
| 279 cert_db_->ImportFromPKCS12(GetPublicModule(), | 279 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 280 pkcs12_data, | 280 pkcs12_data, |
| 281 base::string16(), | 281 base::string16(), |
| 282 true, // is_extractable | 282 true, // is_extractable |
| 283 NULL)); | 283 NULL)); |
| 284 | 284 |
| 285 // Test db should still be empty. | 285 // Test db should still be empty. |
| 286 EXPECT_EQ(0U, ListCerts().size()); | 286 EXPECT_EQ(0U, ListCerts().size()); |
| 287 } | 287 } |
| 288 | 288 |
| 289 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12EmptyPassword) { | 289 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12EmptyPassword) { |
| 290 std::string pkcs12_data = ReadTestFile("client-empty-password.p12"); | 290 std::string pkcs12_data = ReadTestFile("client-empty-password.p12"); |
| 291 | 291 |
| 292 EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(GetPublicModule(), pkcs12_data, | 292 EXPECT_EQ(OK, |
| 293 base::string16(), | 293 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 294 true, // is_extractable | 294 pkcs12_data, |
| 295 NULL)); | 295 base::string16(), |
| 296 true, // is_extractable |
| 297 NULL)); |
| 296 EXPECT_EQ(1U, ListCerts().size()); | 298 EXPECT_EQ(1U, ListCerts().size()); |
| 297 } | 299 } |
| 298 | 300 |
| 299 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12NullPassword) { | 301 TEST_F(CertDatabaseNSSTest, ImportFromPKCS12NullPassword) { |
| 300 std::string pkcs12_data = ReadTestFile("client-null-password.p12"); | 302 std::string pkcs12_data = ReadTestFile("client-null-password.p12"); |
| 301 | 303 |
| 302 EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(GetPublicModule(), pkcs12_data, | 304 EXPECT_EQ(OK, |
| 303 base::string16(), | 305 cert_db_->ImportFromPKCS12(GetPublicSlot(), |
| 304 true, // is_extractable | 306 pkcs12_data, |
| 305 NULL)); | 307 base::string16(), |
| 308 true, // is_extractable |
| 309 NULL)); |
| 306 EXPECT_EQ(1U, ListCerts().size()); | 310 EXPECT_EQ(1U, ListCerts().size()); |
| 307 } | 311 } |
| 308 | 312 |
| 309 TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) { | 313 TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) { |
| 310 CertificateList certs = CreateCertificateListFromFile( | 314 CertificateList certs = CreateCertificateListFromFile( |
| 311 GetTestCertsDirectory(), "root_ca_cert.pem", | 315 GetTestCertsDirectory(), "root_ca_cert.pem", |
| 312 X509Certificate::FORMAT_AUTO); | 316 X509Certificate::FORMAT_AUTO); |
| 313 ASSERT_EQ(1U, certs.size()); | 317 ASSERT_EQ(1U, certs.size()); |
| 314 EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); | 318 EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); |
| 315 | 319 |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, | 1014 EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, |
| 1011 cert_db_->GetCertTrust(certs2[0].get(), SERVER_CERT)); | 1015 cert_db_->GetCertTrust(certs2[0].get(), SERVER_CERT)); |
| 1012 | 1016 |
| 1013 new_certs = ListCerts(); | 1017 new_certs = ListCerts(); |
| 1014 ASSERT_EQ(2U, new_certs.size()); | 1018 ASSERT_EQ(2U, new_certs.size()); |
| 1015 EXPECT_STRNE(new_certs[0]->os_cert_handle()->nickname, | 1019 EXPECT_STRNE(new_certs[0]->os_cert_handle()->nickname, |
| 1016 new_certs[1]->os_cert_handle()->nickname); | 1020 new_certs[1]->os_cert_handle()->nickname); |
| 1017 } | 1021 } |
| 1018 | 1022 |
| 1019 } // namespace net | 1023 } // namespace net |
| OLD | NEW |