Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / quic / crypto / proof_test.cc
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
3 // found in the LICENSE file.
4
5 #include "base/files/file_path.h"
6 #include "net/base/net_errors.h"
7 #include "net/base/test_completion_callback.h"
8 #include "net/base/test_data_directory.h"
9 #include "net/cert/cert_status_flags.h"
10 #include "net/cert/cert_verify_result.h"
11 #include "net/cert/x509_certificate.h"
12 #include "net/quic/crypto/proof_source.h"
13 #include "net/quic/crypto/proof_verifier.h"
14 #include "net/quic/test_tools/crypto_test_utils.h"
15 #include "net/test/cert_test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 #if defined(OS_WIN)
19 #include "base/win/windows_version.h"
20 #endif
21
22 using std::string;
23 using std::vector;
24
25 namespace net {
26 namespace test {
27 namespace {
28
29 // TestProofVerifierCallback is a simple callback for a ProofVerifier that
30 // signals a TestCompletionCallback when called and stores the results from the
31 // ProofVerifier in pointers passed to the constructor.
32 class TestProofVerifierCallback : public ProofVerifierCallback {
33  public:
34   TestProofVerifierCallback(TestCompletionCallback* comp_callback,
35                             bool* ok,
36                             string* error_details)
37       : comp_callback_(comp_callback),
38         ok_(ok),
39         error_details_(error_details) {}
40
41   virtual void Run(bool ok,
42                    const string& error_details,
43                    scoped_ptr<ProofVerifyDetails>* details) OVERRIDE {
44     *ok_ = ok;
45     *error_details_ = error_details;
46
47     comp_callback_->callback().Run(0);
48   }
49
50  private:
51   TestCompletionCallback* const comp_callback_;
52   bool* const ok_;
53   string* const error_details_;
54 };
55
56 // RunVerification runs |verifier->VerifyProof| and asserts that the result
57 // matches |expected_ok|.
58 void RunVerification(ProofVerifier* verifier,
59                      const string& hostname,
60                      const string& server_config,
61                      const vector<string>& certs,
62                      const string& proof,
63                      bool expected_ok) {
64   scoped_ptr<ProofVerifyDetails> details;
65   TestCompletionCallback comp_callback;
66   bool ok;
67   string error_details;
68   scoped_ptr<ProofVerifyContext> verify_context(
69       CryptoTestUtils::ProofVerifyContextForTesting());
70   TestProofVerifierCallback* callback =
71       new TestProofVerifierCallback(&comp_callback, &ok, &error_details);
72
73   QuicAsyncStatus status = verifier->VerifyProof(
74       hostname, server_config, certs, proof, verify_context.get(),
75       &error_details, &details, callback);
76
77   switch (status) {
78     case QUIC_FAILURE:
79       delete callback;
80       ASSERT_FALSE(expected_ok);
81       ASSERT_NE("", error_details);
82       return;
83     case QUIC_SUCCESS:
84       delete callback;
85       ASSERT_TRUE(expected_ok);
86       ASSERT_EQ("", error_details);
87       return;
88     case QUIC_PENDING:
89       comp_callback.WaitForResult();
90       ASSERT_EQ(expected_ok, ok);
91       break;
92   }
93 }
94
95 // Reads the certificate named "quic_" + |file_name| in the test data directory.
96 // The certificate must be PEM encoded. Returns the DER-encoded certificate.
97 string LoadTestCert(const string& file_name) {
98   base::FilePath certs_dir = GetTestCertsDirectory();
99   scoped_refptr<X509Certificate> cert =
100       ImportCertFromFile(certs_dir, "quic_" + file_name);
101   CHECK_NE(static_cast<X509Certificate*>(NULL), cert.get());
102
103   string der_bytes;
104   CHECK(X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes));
105   return der_bytes;
106 }
107
108 }  // namespace
109
110 // TODO(rtenneti): Enable testing of ProofVerifier.
111 TEST(ProofTest, DISABLED_Verify) {
112   scoped_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting());
113   scoped_ptr<ProofVerifier> verifier(
114       CryptoTestUtils::ProofVerifierForTesting());
115
116   const string server_config = "server config bytes";
117   const string hostname = "test.example.com";
118   const vector<string>* certs;
119   const vector<string>* first_certs;
120   string error_details, signature, first_signature;
121
122   ASSERT_TRUE(source->GetProof(hostname, server_config, false /* no ECDSA */,
123                                &first_certs, &first_signature));
124   ASSERT_TRUE(source->GetProof(hostname, server_config, false /* no ECDSA */,
125                                &certs, &signature));
126
127   // Check that the proof source is caching correctly:
128   ASSERT_EQ(first_certs, certs);
129   ASSERT_EQ(signature, first_signature);
130
131   RunVerification(
132       verifier.get(), hostname, server_config, *certs, signature, true);
133
134   RunVerification(
135       verifier.get(), "foo.com", server_config, *certs, signature, false);
136
137   RunVerification(
138       verifier.get(), server_config.substr(1, string::npos), server_config,
139       *certs, signature, false);
140
141   const string corrupt_signature = "1" + signature;
142   RunVerification(
143       verifier.get(), hostname, server_config, *certs, corrupt_signature,
144       false);
145
146   vector<string> wrong_certs;
147   for (size_t i = 1; i < certs->size(); i++) {
148     wrong_certs.push_back((*certs)[i]);
149   }
150   RunVerification(
151       verifier.get(), "foo.com", server_config, wrong_certs, corrupt_signature,
152       false);
153 }
154
155 // A known answer test that allows us to test ProofVerifier without a working
156 // ProofSource.
157 TEST(ProofTest, VerifyRSAKnownAnswerTest) {
158   // These sample signatures were generated by running the Proof.Verify test
159   // and dumping the bytes of the |signature| output of ProofSource::GetProof().
160   static const unsigned char signature_data_0[] = {
161     0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
162     0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
163     0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
164     0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
165     0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
166     0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
167     0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
168     0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
169     0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
170     0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
171     0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
172     0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
173     0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
174     0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
175     0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
176     0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
177     0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
178     0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
179     0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
180     0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
181     0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
182     0xc4, 0x4b, 0x53, 0x54,
183   };
184   static const unsigned char signature_data_1[] = {
185     0x01, 0x7b, 0x52, 0x35, 0xe3, 0x51, 0xdd, 0xf1, 0x67, 0x8d, 0x31, 0x5e,
186     0xa3, 0x75, 0x1f, 0x68, 0x6c, 0xdd, 0x41, 0x7a, 0x18, 0x25, 0xe0, 0x12,
187     0x6e, 0x84, 0x46, 0x5e, 0xb2, 0x98, 0xd7, 0x84, 0xe1, 0x62, 0xe0, 0xc1,
188     0xc4, 0xd7, 0x4f, 0x4f, 0x80, 0xc1, 0x92, 0xd6, 0x02, 0xaf, 0xca, 0x28,
189     0x9f, 0xe0, 0xf3, 0x74, 0xd7, 0xf1, 0x44, 0x67, 0x59, 0x27, 0xc8, 0xc2,
190     0x8b, 0xd4, 0xe5, 0x4a, 0x07, 0xfd, 0x00, 0xd6, 0x8a, 0xbf, 0x8b, 0xcd,
191     0x6a, 0xe0, 0x1d, 0xf6, 0x4b, 0x68, 0x0f, 0xcf, 0xb9, 0xd0, 0xa1, 0xbc,
192     0x2e, 0xcf, 0x7c, 0x03, 0x47, 0x11, 0xe4, 0x4c, 0xbc, 0x1b, 0x6b, 0xa5,
193     0x2a, 0x82, 0x86, 0xa4, 0x7f, 0x1d, 0x85, 0x64, 0x21, 0x10, 0xd2, 0xb2,
194     0xa0, 0x31, 0xa2, 0x78, 0xe6, 0xf2, 0xea, 0x96, 0x38, 0x8c, 0x9a, 0xe1,
195     0x01, 0xab, 0x8e, 0x95, 0x66, 0xc8, 0xe5, 0xcc, 0x80, 0xa3, 0xbd, 0x16,
196     0xa7, 0x79, 0x19, 0x39, 0x61, 0x3d, 0xff, 0x37, 0xca, 0x9f, 0x97, 0x05,
197     0xc7, 0xcb, 0xf0, 0xea, 0xaf, 0x64, 0x07, 0xc0, 0xed, 0x2a, 0x98, 0xa4,
198     0xaf, 0x04, 0x6f, 0xf2, 0xc9, 0xb2, 0x73, 0x9a, 0x56, 0x85, 0x43, 0x64,
199     0x5f, 0xaa, 0xb7, 0xff, 0x31, 0x4c, 0x2e, 0x6c, 0x17, 0xcf, 0xe5, 0xbe,
200     0x7f, 0x7e, 0xad, 0xf5, 0x6f, 0x84, 0x50, 0x20, 0x29, 0xb3, 0x57, 0xe7,
201     0xb1, 0xdc, 0x2c, 0x95, 0x48, 0xfe, 0xb0, 0xc1, 0x92, 0xda, 0xc5, 0x58,
202     0x95, 0xb0, 0x1a, 0x3a, 0x05, 0x71, 0x3c, 0x6d, 0x20, 0x01, 0x4c, 0xa9,
203     0xe4, 0x38, 0x08, 0x65, 0xb4, 0xbd, 0x86, 0x76, 0xbd, 0xad, 0x25, 0x06,
204     0x74, 0x0b, 0xca, 0x95, 0x27, 0x0c, 0x13, 0x08, 0x7e, 0x30, 0xcf, 0xf6,
205     0xb5, 0xc1, 0x2a, 0x08, 0xfc, 0x4b, 0xc6, 0xb5, 0x2f, 0x23, 0x27, 0x32,
206     0x89, 0xdb, 0x0e, 0x4a,
207   };
208   static const unsigned char signature_data_2[] = {
209     0x6d, 0x7d, 0x22, 0x8c, 0x85, 0xc4, 0x8a, 0x80, 0x05, 0xe4, 0x3c, 0xaf,
210     0x10, 0x3b, 0xe3, 0x51, 0xb1, 0x86, 0x52, 0x63, 0xb6, 0x17, 0x33, 0xbd,
211     0x1b, 0x1e, 0xc4, 0x50, 0x10, 0xfc, 0xcc, 0xea, 0x6b, 0x11, 0xeb, 0x6d,
212     0x5e, 0x00, 0xe7, 0xf3, 0x67, 0x99, 0x74, 0x53, 0x12, 0x8f, 0xe4, 0x3e,
213     0x20, 0x17, 0x8e, 0x83, 0xe6, 0xdc, 0x83, 0x91, 0x0e, 0xf3, 0x69, 0x22,
214     0x95, 0x14, 0xdf, 0xc1, 0xda, 0xb5, 0xdb, 0x6a, 0x1a, 0xb4, 0x4f, 0x26,
215     0xd0, 0x32, 0x1d, 0x73, 0x95, 0x1f, 0x39, 0x1d, 0x00, 0xcb, 0xc3, 0x92,
216     0x49, 0x53, 0xcb, 0x5c, 0x36, 0x70, 0x19, 0xd9, 0x64, 0x36, 0xda, 0xfb,
217     0x20, 0xe5, 0x47, 0xd9, 0x08, 0xc6, 0x5a, 0x9e, 0x87, 0x1a, 0xdb, 0x11,
218     0x7b, 0x17, 0xfc, 0x53, 0x7b, 0xc1, 0xa0, 0xc0, 0x33, 0xcf, 0x96, 0xba,
219     0x03, 0x79, 0x8e, 0xc6, 0x05, 0xd2, 0xb7, 0xa2, 0xe2, 0xc1, 0x67, 0xb7,
220     0x6a, 0xeb, 0xb1, 0x40, 0xbb, 0x7d, 0x57, 0xcb, 0xc2, 0x60, 0x9f, 0xf1,
221     0x72, 0xe5, 0xad, 0xce, 0x95, 0x45, 0x7c, 0xbc, 0x75, 0x81, 0x45, 0x19,
222     0xe1, 0xa7, 0x2f, 0x05, 0x52, 0xeb, 0xed, 0xdd, 0x19, 0xd9, 0x1a, 0xc9,
223     0x5a, 0x06, 0x8e, 0x29, 0x54, 0xb5, 0x4f, 0x80, 0xaa, 0x36, 0x36, 0xc0,
224     0xff, 0x64, 0xac, 0xe8, 0x0f, 0x99, 0x35, 0x5e, 0xc6, 0x72, 0x1f, 0x8c,
225     0xc4, 0x2b, 0x7d, 0xc1, 0xfb, 0xf0, 0x12, 0x61, 0xb1, 0x18, 0x65, 0xdd,
226     0xc2, 0x38, 0x92, 0xba, 0x84, 0xf8, 0xc8, 0x5e, 0x17, 0x63, 0xe0, 0x9c,
227     0x2c, 0xe6, 0x70, 0x71, 0xdc, 0xe5, 0xc1, 0xea, 0xb3, 0x9a, 0xb6, 0x91,
228     0xdc, 0xc5, 0x56, 0x84, 0x8a, 0x31, 0x31, 0x23, 0x61, 0x94, 0x7e, 0x01,
229     0x22, 0x49, 0xf3, 0xcb, 0x0e, 0x31, 0x03, 0x04, 0x1b, 0x14, 0x43, 0x7c,
230     0xad, 0x42, 0xe5, 0x55,
231   };
232
233   scoped_ptr<ProofVerifier> verifier(
234       CryptoTestUtils::ProofVerifierForTesting());
235
236   const string server_config = "server config bytes";
237   const string hostname = "test.example.com";
238
239   vector<string> certs(2);
240   certs[0] = LoadTestCert("test.example.com.crt");
241   certs[1] = LoadTestCert("intermediate.crt");
242
243   // Signatures are nondeterministic, so we test multiple signatures on the
244   // same server_config.
245   vector<string> signatures(3);
246   signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
247                        sizeof(signature_data_0));
248   signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
249                        sizeof(signature_data_1));
250   signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
251                        sizeof(signature_data_2));
252
253   for (size_t i = 0; i < signatures.size(); i++) {
254     const string& signature = signatures[i];
255
256     RunVerification(
257         verifier.get(), hostname, server_config, certs, signature, true);
258     RunVerification(
259         verifier.get(), "foo.com", server_config, certs, signature, false);
260     RunVerification(
261         verifier.get(), hostname, server_config.substr(1, string::npos),
262         certs, signature, false);
263
264     const string corrupt_signature = "1" + signature;
265     RunVerification(
266         verifier.get(), hostname, server_config, certs, corrupt_signature,
267         false);
268
269     vector<string> wrong_certs;
270     for (size_t i = 1; i < certs.size(); i++) {
271       wrong_certs.push_back(certs[i]);
272     }
273     RunVerification(verifier.get(), hostname, server_config, wrong_certs,
274                     signature, false);
275   }
276 }
277
278 // A known answer test that allows us to test ProofVerifier without a working
279 // ProofSource.
280 TEST(ProofTest, VerifyECDSAKnownAnswerTest) {
281   // Disable this test on platforms that do not support ECDSA certificates.
282 #if defined(OS_WIN)
283   if (base::win::GetVersion() < base::win::VERSION_VISTA)
284     return;
285 #endif
286
287   // These sample signatures were generated by running the Proof.Verify test
288   // (modified to use ECDSA for signing proofs) and dumping the bytes of the
289   // |signature| output of ProofSource::GetProof().
290   static const unsigned char signature_data_0[] = {
291     0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0xc4, 0x7d, 0x08, 0xd1, 0x49, 0x19,
292     0x6c, 0xd1, 0x7c, 0xb9, 0x25, 0xe0, 0xe3, 0xbd, 0x6a, 0x5c, 0xd7, 0xaa,
293     0x0c, 0xdc, 0x4f, 0x8e, 0xeb, 0xde, 0xbf, 0x32, 0xf8, 0xd1, 0x84, 0x95,
294     0x97, 0x02, 0x20, 0x29, 0x3d, 0x49, 0x22, 0x73, 0xed, 0x8b, 0xde, 0x3d,
295     0xc2, 0xa4, 0x20, 0xcc, 0xe7, 0xc8, 0x2a, 0x85, 0x20, 0x9b, 0x5b, 0xda,
296     0xcd, 0x58, 0x23, 0xbe, 0x89, 0x73, 0x31, 0x87, 0x51, 0xd1, 0x01,
297   };
298   static const unsigned char signature_data_1[] = {
299     0x30, 0x46, 0x02, 0x21, 0x00, 0xec, 0xdf, 0x69, 0xc8, 0x24, 0x59, 0x93,
300     0xda, 0x49, 0xee, 0x37, 0x28, 0xaf, 0xeb, 0x0e, 0x2f, 0x80, 0x17, 0x4b,
301     0x3b, 0xf6, 0x54, 0xcd, 0x3b, 0x86, 0xc5, 0x98, 0x0d, 0xff, 0xc6, 0xb1,
302     0xe7, 0x02, 0x21, 0x00, 0xe1, 0x36, 0x8c, 0xc0, 0xf4, 0x50, 0x5f, 0xba,
303     0xfb, 0xe2, 0xff, 0x1d, 0x5d, 0x64, 0xe4, 0x07, 0xbb, 0x5a, 0x4b, 0x19,
304     0xb6, 0x39, 0x7a, 0xc4, 0x12, 0xc6, 0xe5, 0x42, 0xc8, 0x78, 0x33, 0xcd,
305   };
306   static const unsigned char signature_data_2[] = {
307     0x30, 0x45, 0x02, 0x20, 0x09, 0x51, 0xe9, 0xde, 0xdb, 0x01, 0xfd, 0xb4,
308     0xd8, 0x20, 0xbb, 0xad, 0x41, 0xe3, 0xaa, 0xe7, 0xa3, 0xc3, 0x32, 0x10,
309     0x9d, 0xfa, 0x37, 0xce, 0x17, 0xd1, 0x29, 0xf9, 0xd4, 0x1d, 0x0d, 0x19,
310     0x02, 0x21, 0x00, 0xc6, 0x20, 0xd4, 0x28, 0xf9, 0x70, 0xb5, 0xb4, 0xff,
311     0x4a, 0x35, 0xba, 0xa0, 0xf2, 0x8e, 0x00, 0xf7, 0xcb, 0x43, 0xaf, 0x2d,
312     0x1f, 0xce, 0x92, 0x05, 0xca, 0x29, 0xfe, 0xd2, 0x8f, 0xd9, 0x31,
313   };
314
315   scoped_ptr<ProofVerifier> verifier(
316       CryptoTestUtils::ProofVerifierForTesting());
317
318   const string server_config = "server config bytes";
319   const string hostname = "test.example.com";
320
321   vector<string> certs(2);
322   certs[0] = LoadTestCert("test_ecc.example.com.crt");
323   certs[1] = LoadTestCert("intermediate.crt");
324
325   // Signatures are nondeterministic, so we test multiple signatures on the
326   // same server_config.
327   vector<string> signatures(3);
328   signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
329                        sizeof(signature_data_0));
330   signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
331                        sizeof(signature_data_1));
332   signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
333                        sizeof(signature_data_2));
334
335   for (size_t i = 0; i < signatures.size(); i++) {
336     const string& signature = signatures[i];
337
338     RunVerification(
339         verifier.get(), hostname, server_config, certs, signature, true);
340     RunVerification(
341         verifier.get(), "foo.com", server_config, certs, signature, false);
342     RunVerification(
343         verifier.get(), hostname, server_config.substr(1, string::npos),
344         certs, signature, false);
345
346     // An ECDSA signature is DER-encoded. Corrupt the last byte so that the
347     // signature can still be DER-decoded correctly.
348     string corrupt_signature = signature;
349     corrupt_signature[corrupt_signature.size() - 1] += 1;
350     RunVerification(
351         verifier.get(), hostname, server_config, certs, corrupt_signature,
352         false);
353
354     // Prepending a "1" makes the DER invalid.
355     const string bad_der_signature1 = "1" + signature;
356     RunVerification(
357         verifier.get(), hostname, server_config, certs, bad_der_signature1,
358         false);
359
360     vector<string> wrong_certs;
361     for (size_t i = 1; i < certs.size(); i++) {
362       wrong_certs.push_back(certs[i]);
363     }
364     RunVerification(
365         verifier.get(), hostname, server_config, wrong_certs, signature,
366         false);
367   }
368 }
369
370 }  // namespace test
371 }  // namespace net