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

Side by Side Diff: net/base/keygen_handler_unittest.cc

Issue 2838010: Add a unit test to check KeygenHandler's thread-safety (Closed)
Patch Set: Another revision Created 10 years, 6 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/base/keygen_handler.h" 5 #include "net/base/keygen_handler.h"
6 6
7 #if defined(USE_NSS)
8 #include <private/pprthred.h> // PR_DetachThread
9 #endif
10
7 #include <string> 11 #include <string>
8 12
9 #include "base/base64.h" 13 #include "base/base64.h"
10 #include "base/logging.h" 14 #include "base/logging.h"
11 #include "base/nss_util.h" 15 #include "base/nss_util.h"
16 #include "base/task.h"
17 #include "base/waitable_event.h"
18 #include "base/worker_pool.h"
12 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
13 20
14 namespace net { 21 namespace net {
15 22
16 namespace { 23 namespace {
17 24
18 KeygenHandler::KeyLocation ValidKeyLocation() { 25 KeygenHandler::KeyLocation ValidKeyLocation() {
19 KeygenHandler::KeyLocation result; 26 KeygenHandler::KeyLocation result;
20 #if defined(OS_WIN) 27 #if defined(OS_WIN)
21 result.container_name = L"Unit tests"; 28 result.container_name = L"Unit tests";
(...skipping 12 matching lines...) Expand all
34 KeygenHandlerTest() {} 41 KeygenHandlerTest() {}
35 virtual ~KeygenHandlerTest() {} 42 virtual ~KeygenHandlerTest() {}
36 43
37 virtual void SetUp() { 44 virtual void SetUp() {
38 #if defined(OS_CHROMEOS) 45 #if defined(OS_CHROMEOS)
39 base::OpenPersistentNSSDB(); 46 base::OpenPersistentNSSDB();
40 #endif 47 #endif
41 } 48 }
42 }; 49 };
43 50
44 TEST_F(KeygenHandlerTest, FLAKY_SmokeTest) { 51 // Assert that |result| is a valid output for KeygenHandler given challenge
45 KeygenHandler handler(2048, "some challenge"); 52 // string of |challenge|.
46 handler.set_stores_key(false); // Don't leave the key-pair behind 53 void AssertValidSignedPublicKeyAndChallenge(const std::string& result,
47 std::string result = handler.GenKeyAndSignChallenge(); 54 const std::string& challenge) {
48 LOG(INFO) << "KeygenHandler produced: " << result;
49 ASSERT_GT(result.length(), 0U); 55 ASSERT_GT(result.length(), 0U);
50 56
51 // Verify it's valid base64: 57 // Verify it's valid base64:
52 std::string spkac; 58 std::string spkac;
53 ASSERT_TRUE(base::Base64Decode(result, &spkac)); 59 ASSERT_TRUE(base::Base64Decode(result, &spkac));
54 // In lieu of actually parsing and validating the DER data, 60 // In lieu of actually parsing and validating the DER data,
55 // just check that it exists and has a reasonable length. 61 // just check that it exists and has a reasonable length.
56 // (It's almost always 590 bytes, but the DER encoding of the random key 62 // (It's almost always 590 bytes, but the DER encoding of the random key
57 // and signature could sometimes be a few bytes different.) 63 // and signature could sometimes be a few bytes different.)
58 ASSERT_GE(spkac.length(), 580U); 64 ASSERT_GE(spkac.length(), 580U);
(...skipping 12 matching lines...) Expand all
71 // Exponent: 65537 (0x10001) 77 // Exponent: 65537 (0x10001)
72 // Challenge String: some challenge 78 // Challenge String: some challenge
73 // Signature Algorithm: md5WithRSAEncryption 79 // Signature Algorithm: md5WithRSAEncryption
74 // 92:f3:cc:ff:0b:d3:d0:4a:3a:4c:ba:ff:d6:38:7f:a5:4b:b5: ..... 80 // 92:f3:cc:ff:0b:d3:d0:4a:3a:4c:ba:ff:d6:38:7f:a5:4b:b5: .....
75 // Signature OK 81 // Signature OK
76 // 82 //
77 // The value of |spkac| can be ASN.1-parsed with: 83 // The value of |spkac| can be ASN.1-parsed with:
78 // openssl asn1parse -inform DER 84 // openssl asn1parse -inform DER
79 } 85 }
80 86
87 TEST_F(KeygenHandlerTest, FLAKY_SmokeTest) {
88 KeygenHandler handler(2048, "some challenge");
89 handler.set_stores_key(false); // Don't leave the key-pair behind
90 std::string result = handler.GenKeyAndSignChallenge();
91 LOG(INFO) << "KeygenHandler produced: " << result;
92 AssertValidSignedPublicKeyAndChallenge(result, "some challenge");
93 }
94
81 TEST_F(KeygenHandlerTest, Cache) { 95 TEST_F(KeygenHandlerTest, Cache) {
82 KeygenHandler::Cache* cache = KeygenHandler::Cache::GetInstance(); 96 KeygenHandler::Cache* cache = KeygenHandler::Cache::GetInstance();
83 KeygenHandler::KeyLocation location1; 97 KeygenHandler::KeyLocation location1;
84 KeygenHandler::KeyLocation location2; 98 KeygenHandler::KeyLocation location2;
85 99
86 std::string key1("abcd"); 100 std::string key1("abcd");
87 cache->Insert(key1, location1); 101 cache->Insert(key1, location1);
88 102
89 // The cache should have stored location1 at key1. 103 // The cache should have stored location1 at key1.
90 EXPECT_TRUE(cache->Find(key1, &location2)); 104 EXPECT_TRUE(cache->Find(key1, &location2));
91 105
92 // The cache should have retrieved it into location2, and their equality 106 // The cache should have retrieved it into location2, and their equality
93 // should be reflexive. 107 // should be reflexive.
94 EXPECT_TRUE(location1.Equals(location2)); 108 EXPECT_TRUE(location1.Equals(location2));
95 EXPECT_TRUE(location2.Equals(location1)); 109 EXPECT_TRUE(location2.Equals(location1));
96 110
97 location2 = ValidKeyLocation(); 111 location2 = ValidKeyLocation();
98 KeygenHandler::KeyLocation location3 = ValidKeyLocation(); 112 KeygenHandler::KeyLocation location3 = ValidKeyLocation();
99 EXPECT_FALSE(location1.Equals(location2)); 113 EXPECT_FALSE(location1.Equals(location2));
100 114
101 // The cache should miss for an unregistered key. 115 // The cache should miss for an unregistered key.
102 std::string key2("def"); 116 std::string key2("def");
103 EXPECT_FALSE(cache->Find(key2, &location2)); 117 EXPECT_FALSE(cache->Find(key2, &location2));
104 118
105 // A cache miss should leave the original location unmolested. 119 // A cache miss should leave the original location unmolested.
106 EXPECT_TRUE(location2.Equals(location3)); 120 EXPECT_TRUE(location2.Equals(location3));
107 } 121 }
108 122
123 class ConcurrencyTestTask : public Task {
124 public:
125 ConcurrencyTestTask(base::WaitableEvent* event,
126 const std::string& challenge, std::string* result)
127 : event_(event),
128 challenge_(challenge),
129 result_(result) {
130 }
131
132 virtual void Run() {
133 KeygenHandler handler(2048, "some challenge");
134 handler.set_stores_key(false); // Don't leave the key-pair behind.
135 *result_ = handler.GenKeyAndSignChallenge();
136 event_->Signal();
137 #if defined(USE_NSS)
138 // Detach the thread from NSPR.
139 // Calling NSS functions attaches the thread to NSPR, which stores
140 // the NSPR thread ID in thread-specific data.
141 // The threads in our thread pool terminate after we have called
142 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets
143 // segfaults on shutdown when the threads' thread-specific data
144 // destructors run.
145 PR_DetachThread();
146 #endif
147 }
148
149 private:
150 base::WaitableEvent* event_;
151 std::string challenge_;
152 std::string* result_;
153 };
154
155 // We asynchronously generate the keys so as not to hang up the IO thread. This
156 // test tries to catch concurrency problems in the keygen implementation.
157 TEST_F(KeygenHandlerTest, ConcurrencyTest) {
158 const int NUM_HANDLERS = 5;
159 base::WaitableEvent* events[NUM_HANDLERS] = { NULL };
160 std::string results[NUM_HANDLERS];
161 for (int i = 0; i < NUM_HANDLERS; i++) {
162 events[i] = new base::WaitableEvent(false, false);
163 WorkerPool::PostTask(FROM_HERE,
164 new ConcurrencyTestTask(events[i], "some challenge",
165 &results[i]),
166 true);
167 }
168
169 for (int i = 0; i < NUM_HANDLERS; i++) {
170 // Make sure the job completed
171 bool signaled = events[i]->Wait();
172 EXPECT_TRUE(signaled);
173 delete events[i];
174 events[i] = NULL;
175
176 LOG(INFO) << "KeygenHandler " << i << " produced: " << results[i];
177 AssertValidSignedPublicKeyAndChallenge(results[i], "some challenge");
178 }
179 }
180
109 } // namespace 181 } // namespace
110 182
111 } // namespace net 183 } // namespace net
OLDNEW
« base/nss_util.cc ('K') | « base/nss_util.cc ('k') | net/net.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698