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