Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: net/ssl/openssl_client_key_store_unittest.cc

Issue 2291213002: Remove ENGINE indirection from Android SSLPrivateKey. (Closed)
Patch Set: re-delete undeleted files Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/ssl/openssl_client_key_store.cc ('k') | net/ssl/ssl_platform_key_android.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/ssl/openssl_client_key_store.h" 5 #include "net/ssl/openssl_client_key_store.h"
6 6
7 #include "base/logging.h"
7 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
8 #include "crypto/scoped_openssl_types.h" 9 #include "crypto/scoped_openssl_types.h"
10 #include "net/ssl/ssl_private_key.h"
9 #include "net/test/cert_test_util.h" 11 #include "net/test/cert_test_util.h"
10 #include "net/test/test_data_directory.h" 12 #include "net/test/test_data_directory.h"
11 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
12 14
13 namespace net { 15 namespace net {
14 16
15 namespace { 17 namespace {
16 18
17 // Return the internal reference count of a given EVP_PKEY.
18 int EVP_PKEY_get_refcount(EVP_PKEY* pkey) {
19 return pkey->references;
20 }
21
22 // A common test class to ensure that the store is flushed after 19 // A common test class to ensure that the store is flushed after
23 // each test. 20 // each test.
24 class OpenSSLClientKeyStoreTest : public ::testing::Test { 21 class OpenSSLClientKeyStoreTest : public ::testing::Test {
25 public: 22 public:
26 OpenSSLClientKeyStoreTest() 23 OpenSSLClientKeyStoreTest()
27 : store_(OpenSSLClientKeyStore::GetInstance()) { 24 : store_(OpenSSLClientKeyStore::GetInstance()) {
28 } 25 }
29 26
30 ~OpenSSLClientKeyStoreTest() override { 27 ~OpenSSLClientKeyStoreTest() override {
31 if (store_) 28 if (store_)
32 store_->Flush(); 29 store_->Flush();
33 } 30 }
34 31
35 protected: 32 protected:
36 OpenSSLClientKeyStore* store_; 33 OpenSSLClientKeyStore* store_;
37 }; 34 };
38 35
36 class MockSSLPrivateKey : public SSLPrivateKey {
37 public:
38 MockSSLPrivateKey() : on_destroyed_(nullptr) {}
39
40 void set_on_destroyed(bool* on_destroyed) { on_destroyed_ = on_destroyed; }
41
42 Type GetType() override {
43 NOTREACHED();
44 return Type::RSA;
45 }
46
47 std::vector<Hash> GetDigestPreferences() override {
48 NOTREACHED();
49 return {};
50 }
51
52 size_t GetMaxSignatureLengthInBytes() override {
53 NOTREACHED();
54 return 0;
55 }
56
57 void SignDigest(Hash hash,
58 const base::StringPiece& input,
59 const SignCallback& callback) override {
60 NOTREACHED();
61 }
62
63 private:
64 ~MockSSLPrivateKey() override {
65 if (on_destroyed_)
66 *on_destroyed_ = true;
67 }
68
69 bool* on_destroyed_;
70 };
71
39 // Check that GetInstance() returns non-null 72 // Check that GetInstance() returns non-null
40 TEST_F(OpenSSLClientKeyStoreTest, GetInstance) { 73 TEST_F(OpenSSLClientKeyStoreTest, GetInstance) {
41 ASSERT_TRUE(store_); 74 ASSERT_TRUE(store_);
42 } 75 }
43 76
44 // Check that Flush() works correctly. 77 // Check that Flush() works correctly.
45 TEST_F(OpenSSLClientKeyStoreTest, Flush) { 78 TEST_F(OpenSSLClientKeyStoreTest, Flush) {
46 ASSERT_TRUE(store_); 79 ASSERT_TRUE(store_);
47 80
48 scoped_refptr<X509Certificate> cert_1( 81 scoped_refptr<X509Certificate> cert_1(
49 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); 82 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
50 ASSERT_TRUE(cert_1.get()); 83 ASSERT_TRUE(cert_1);
51 84
52 crypto::ScopedEVP_PKEY priv_key(EVP_PKEY_new()); 85 EXPECT_TRUE(store_->RecordClientCertPrivateKey(
53 ASSERT_TRUE(priv_key.get()); 86 cert_1.get(), make_scoped_refptr(new MockSSLPrivateKey)));
54
55 ASSERT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(),
56 priv_key.get()));
57 87
58 store_->Flush(); 88 store_->Flush();
59 89
60 // Retrieve the private key. This should fail because the store 90 // Retrieve the private key. This should fail because the store
61 // was flushed. 91 // was flushed.
62 crypto::ScopedEVP_PKEY pkey = store_->FetchClientCertPrivateKey(cert_1.get()); 92 EXPECT_FALSE(store_->FetchClientCertPrivateKey(cert_1.get()));
63 ASSERT_FALSE(pkey.get());
64 } 93 }
65 94
66 // Check that trying to retrieve the private key of an unknown certificate 95 // Check that trying to retrieve the private key of an unknown certificate
67 // simply fails by returning null. 96 // simply fails by returning null.
68 TEST_F(OpenSSLClientKeyStoreTest, FetchEmptyPrivateKey) { 97 TEST_F(OpenSSLClientKeyStoreTest, FetchEmptyPrivateKey) {
69 ASSERT_TRUE(store_); 98 ASSERT_TRUE(store_);
70 99
71 scoped_refptr<X509Certificate> cert_1( 100 scoped_refptr<X509Certificate> cert_1(
72 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); 101 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
73 ASSERT_TRUE(cert_1.get()); 102 ASSERT_TRUE(cert_1);
74 103
75 // Retrieve the private key now. This should fail because it was 104 // Retrieve the private key now. This should fail because it was
76 // never recorded in the store. 105 // never recorded in the store.
77 crypto::ScopedEVP_PKEY pkey = store_->FetchClientCertPrivateKey(cert_1.get()); 106 EXPECT_FALSE(store_->FetchClientCertPrivateKey(cert_1.get()));
78 ASSERT_FALSE(pkey.get());
79 } 107 }
80 108
81 // Check that any private key recorded through RecordClientCertPrivateKey 109 // Check that any private key recorded through RecordClientCertPrivateKey
82 // can be retrieved with FetchClientCertPrivateKey. 110 // can be retrieved with FetchClientCertPrivateKey.
83 TEST_F(OpenSSLClientKeyStoreTest, RecordAndFetchPrivateKey) { 111 TEST_F(OpenSSLClientKeyStoreTest, RecordAndFetchPrivateKey) {
84 ASSERT_TRUE(store_); 112 ASSERT_TRUE(store_);
85 113
86 // Any certificate / key pair will do, the store is not supposed to 114 // Any certificate / key pair will do, the store is not supposed to
87 // check that the private and certificate public keys match. This is 115 // check that the private and certificate public keys match. This is
88 // by design since the private EVP_PKEY could be a wrapper around a 116 // by design since the private EVP_PKEY could be a wrapper around a
89 // JNI reference, with no way to access the real private key bits. 117 // JNI reference, with no way to access the real private key bits.
90 scoped_refptr<X509Certificate> cert_1( 118 scoped_refptr<X509Certificate> cert_1(
91 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); 119 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
92 ASSERT_TRUE(cert_1.get()); 120 ASSERT_TRUE(cert_1);
93 121
94 crypto::ScopedEVP_PKEY priv_key(EVP_PKEY_new()); 122 bool on_destroyed = false;
95 ASSERT_TRUE(priv_key.get()); 123 scoped_refptr<MockSSLPrivateKey> priv_key(new MockSSLPrivateKey);
96 ASSERT_EQ(1, EVP_PKEY_get_refcount(priv_key.get())); 124 priv_key->set_on_destroyed(&on_destroyed);
97 125
98 // Add the key a first time, this should increment its reference count. 126 // Add a key twice.
99 ASSERT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), 127 EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), priv_key));
100 priv_key.get())); 128 EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), priv_key));
101 ASSERT_EQ(2, EVP_PKEY_get_refcount(priv_key.get()));
102 129
103 // Two successive calls with the same certificate / private key shall 130 // Retrieve the private key.
104 // also succeed, but the key's reference count should not be incremented. 131 scoped_refptr<SSLPrivateKey> pkey2 =
105 ASSERT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), 132 store_->FetchClientCertPrivateKey(cert_1.get());
106 priv_key.get())); 133 EXPECT_EQ(pkey2.get(), priv_key.get());
107 ASSERT_EQ(2, EVP_PKEY_get_refcount(priv_key.get()));
108 134
109 // Retrieve the private key. This should increment the private key's 135 // Flush the key store and release all references. At this point, the private
110 // reference count. 136 // key should be cleanly destroyed.
111 crypto::ScopedEVP_PKEY pkey2 =
112 store_->FetchClientCertPrivateKey(cert_1.get());
113 ASSERT_EQ(pkey2.get(), priv_key.get());
114 ASSERT_EQ(3, EVP_PKEY_get_refcount(priv_key.get()));
115
116 // Flush the store explicitely, this should decrement the private
117 // key's reference count.
118 store_->Flush(); 137 store_->Flush();
119 ASSERT_EQ(2, EVP_PKEY_get_refcount(priv_key.get())); 138 priv_key = nullptr;
139 pkey2 = nullptr;
140 EXPECT_TRUE(on_destroyed);
120 } 141 }
121 142
122 // Same test, but with two certificates / private keys. 143 // Same test, but with two certificates / private keys.
123 TEST_F(OpenSSLClientKeyStoreTest, RecordAndFetchTwoPrivateKeys) { 144 TEST_F(OpenSSLClientKeyStoreTest, RecordAndFetchTwoPrivateKeys) {
124 scoped_refptr<X509Certificate> cert_1( 145 scoped_refptr<X509Certificate> cert_1(
125 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem")); 146 ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
126 ASSERT_TRUE(cert_1.get()); 147 ASSERT_TRUE(cert_1);
127 148
128 scoped_refptr<X509Certificate> cert_2( 149 scoped_refptr<X509Certificate> cert_2(
129 ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem")); 150 ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem"));
130 ASSERT_TRUE(cert_2.get()); 151 ASSERT_TRUE(cert_2);
131 152
132 crypto::ScopedEVP_PKEY priv_key1(EVP_PKEY_new()); 153 scoped_refptr<SSLPrivateKey> priv_key1(new MockSSLPrivateKey);
133 ASSERT_TRUE(priv_key1.get()); 154 scoped_refptr<SSLPrivateKey> priv_key2(new MockSSLPrivateKey);
134 ASSERT_EQ(1, EVP_PKEY_get_refcount(priv_key1.get()));
135 155
136 crypto::ScopedEVP_PKEY priv_key2(EVP_PKEY_new()); 156 EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), priv_key1));
137 ASSERT_TRUE(priv_key2.get()); 157 EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_2.get(), priv_key2));
138 ASSERT_EQ(1, EVP_PKEY_get_refcount(priv_key2.get()));
139 158
140 ASSERT_NE(priv_key1.get(), priv_key2.get()); 159 scoped_refptr<SSLPrivateKey> fetch_key1 =
141
142 // Add the key a first time, this shall succeed, and increment the
143 // reference count.
144 EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(),
145 priv_key1.get()));
146 EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_2.get(),
147 priv_key2.get()));
148 EXPECT_EQ(2, EVP_PKEY_get_refcount(priv_key1.get()));
149 EXPECT_EQ(2, EVP_PKEY_get_refcount(priv_key2.get()));
150
151 // Retrieve the private key now. This shall succeed and increment
152 // the private key's reference count.
153 crypto::ScopedEVP_PKEY fetch_key1 =
154 store_->FetchClientCertPrivateKey(cert_1.get()); 160 store_->FetchClientCertPrivateKey(cert_1.get());
155 crypto::ScopedEVP_PKEY fetch_key2 = 161 scoped_refptr<SSLPrivateKey> fetch_key2 =
156 store_->FetchClientCertPrivateKey(cert_2.get()); 162 store_->FetchClientCertPrivateKey(cert_2.get());
157 163
158 EXPECT_TRUE(fetch_key1.get()); 164 EXPECT_TRUE(fetch_key1);
159 EXPECT_TRUE(fetch_key2.get()); 165 EXPECT_TRUE(fetch_key2);
160 166
161 EXPECT_EQ(fetch_key1.get(), priv_key1.get()); 167 EXPECT_EQ(fetch_key1.get(), priv_key1.get());
162 EXPECT_EQ(fetch_key2.get(), priv_key2.get()); 168 EXPECT_EQ(fetch_key2.get(), priv_key2.get());
163
164 EXPECT_EQ(3, EVP_PKEY_get_refcount(priv_key1.get()));
165 EXPECT_EQ(3, EVP_PKEY_get_refcount(priv_key2.get()));
166 } 169 }
167 170
168 } // namespace 171 } // namespace
169 } // namespace net 172 } // namespace net
OLDNEW
« no previous file with comments | « net/ssl/openssl_client_key_store.cc ('k') | net/ssl/ssl_platform_key_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698