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