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