forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopenssl_client_key_store_unittest.cc
171 lines (133 loc) · 4.98 KB
/
openssl_client_key_store_unittest.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright (c) 2013 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/ssl/openssl_client_key_store.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "net/ssl/ssl_private_key.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
// A common test class to ensure that the store is flushed after
// each test.
class OpenSSLClientKeyStoreTest : public ::testing::Test {
public:
OpenSSLClientKeyStoreTest()
: store_(OpenSSLClientKeyStore::GetInstance()) {
}
~OpenSSLClientKeyStoreTest() override {
if (store_)
store_->Flush();
}
protected:
OpenSSLClientKeyStore* store_;
};
class MockSSLPrivateKey : public SSLPrivateKey {
public:
MockSSLPrivateKey() : on_destroyed_(nullptr) {}
void set_on_destroyed(bool* on_destroyed) { on_destroyed_ = on_destroyed; }
Type GetType() override {
NOTREACHED();
return Type::RSA;
}
std::vector<Hash> GetDigestPreferences() override {
NOTREACHED();
return {};
}
size_t GetMaxSignatureLengthInBytes() override {
NOTREACHED();
return 0;
}
void SignDigest(Hash hash,
const base::StringPiece& input,
const SignCallback& callback) override {
NOTREACHED();
}
private:
~MockSSLPrivateKey() override {
if (on_destroyed_)
*on_destroyed_ = true;
}
bool* on_destroyed_;
};
// Check that GetInstance() returns non-null
TEST_F(OpenSSLClientKeyStoreTest, GetInstance) {
ASSERT_TRUE(store_);
}
// Check that Flush() works correctly.
TEST_F(OpenSSLClientKeyStoreTest, Flush) {
ASSERT_TRUE(store_);
scoped_refptr<X509Certificate> cert_1(
ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
ASSERT_TRUE(cert_1);
EXPECT_TRUE(store_->RecordClientCertPrivateKey(
cert_1.get(), make_scoped_refptr(new MockSSLPrivateKey)));
store_->Flush();
// Retrieve the private key. This should fail because the store
// was flushed.
EXPECT_FALSE(store_->FetchClientCertPrivateKey(cert_1.get()));
}
// Check that trying to retrieve the private key of an unknown certificate
// simply fails by returning null.
TEST_F(OpenSSLClientKeyStoreTest, FetchEmptyPrivateKey) {
ASSERT_TRUE(store_);
scoped_refptr<X509Certificate> cert_1(
ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
ASSERT_TRUE(cert_1);
// Retrieve the private key now. This should fail because it was
// never recorded in the store.
EXPECT_FALSE(store_->FetchClientCertPrivateKey(cert_1.get()));
}
// Check that any private key recorded through RecordClientCertPrivateKey
// can be retrieved with FetchClientCertPrivateKey.
TEST_F(OpenSSLClientKeyStoreTest, RecordAndFetchPrivateKey) {
ASSERT_TRUE(store_);
// Any certificate / key pair will do, the store is not supposed to
// check that the private and certificate public keys match. This is
// by design since the private EVP_PKEY could be a wrapper around a
// JNI reference, with no way to access the real private key bits.
scoped_refptr<X509Certificate> cert_1(
ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
ASSERT_TRUE(cert_1);
bool on_destroyed = false;
scoped_refptr<MockSSLPrivateKey> priv_key(new MockSSLPrivateKey);
priv_key->set_on_destroyed(&on_destroyed);
// Add a key twice.
EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), priv_key));
EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), priv_key));
// Retrieve the private key.
scoped_refptr<SSLPrivateKey> pkey2 =
store_->FetchClientCertPrivateKey(cert_1.get());
EXPECT_EQ(pkey2.get(), priv_key.get());
// Flush the key store and release all references. At this point, the private
// key should be cleanly destroyed.
store_->Flush();
priv_key = nullptr;
pkey2 = nullptr;
EXPECT_TRUE(on_destroyed);
}
// Same test, but with two certificates / private keys.
TEST_F(OpenSSLClientKeyStoreTest, RecordAndFetchTwoPrivateKeys) {
scoped_refptr<X509Certificate> cert_1(
ImportCertFromFile(GetTestCertsDirectory(), "client_1.pem"));
ASSERT_TRUE(cert_1);
scoped_refptr<X509Certificate> cert_2(
ImportCertFromFile(GetTestCertsDirectory(), "client_2.pem"));
ASSERT_TRUE(cert_2);
scoped_refptr<SSLPrivateKey> priv_key1(new MockSSLPrivateKey);
scoped_refptr<SSLPrivateKey> priv_key2(new MockSSLPrivateKey);
EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_1.get(), priv_key1));
EXPECT_TRUE(store_->RecordClientCertPrivateKey(cert_2.get(), priv_key2));
scoped_refptr<SSLPrivateKey> fetch_key1 =
store_->FetchClientCertPrivateKey(cert_1.get());
scoped_refptr<SSLPrivateKey> fetch_key2 =
store_->FetchClientCertPrivateKey(cert_2.get());
EXPECT_TRUE(fetch_key1);
EXPECT_TRUE(fetch_key2);
EXPECT_EQ(fetch_key1.get(), priv_key1.get());
EXPECT_EQ(fetch_key2.get(), priv_key2.get());
}
} // namespace
} // namespace net