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 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     0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
    177     0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
    178     0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
    179     0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
    180     0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
    181     0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
    182     0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
    183     0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
    184     0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
    185     0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
    186     0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
    187     0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
    188     0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
    189     0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
    190     0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
    191     0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
    192     0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
    193     0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
    194     0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
    195     0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
    196     0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
    197     0xc4, 0x4b, 0x53, 0x54,
    198   };
    199   static const unsigned char signature_data_1[] = {
    200     0x01, 0x7b, 0x52, 0x35, 0xe3, 0x51, 0xdd, 0xf1, 0x67, 0x8d, 0x31, 0x5e,
    201     0xa3, 0x75, 0x1f, 0x68, 0x6c, 0xdd, 0x41, 0x7a, 0x18, 0x25, 0xe0, 0x12,
    202     0x6e, 0x84, 0x46, 0x5e, 0xb2, 0x98, 0xd7, 0x84, 0xe1, 0x62, 0xe0, 0xc1,
    203     0xc4, 0xd7, 0x4f, 0x4f, 0x80, 0xc1, 0x92, 0xd6, 0x02, 0xaf, 0xca, 0x28,
    204     0x9f, 0xe0, 0xf3, 0x74, 0xd7, 0xf1, 0x44, 0x67, 0x59, 0x27, 0xc8, 0xc2,
    205     0x8b, 0xd4, 0xe5, 0x4a, 0x07, 0xfd, 0x00, 0xd6, 0x8a, 0xbf, 0x8b, 0xcd,
    206     0x6a, 0xe0, 0x1d, 0xf6, 0x4b, 0x68, 0x0f, 0xcf, 0xb9, 0xd0, 0xa1, 0xbc,
    207     0x2e, 0xcf, 0x7c, 0x03, 0x47, 0x11, 0xe4, 0x4c, 0xbc, 0x1b, 0x6b, 0xa5,
    208     0x2a, 0x82, 0x86, 0xa4, 0x7f, 0x1d, 0x85, 0x64, 0x21, 0x10, 0xd2, 0xb2,
    209     0xa0, 0x31, 0xa2, 0x78, 0xe6, 0xf2, 0xea, 0x96, 0x38, 0x8c, 0x9a, 0xe1,
    210     0x01, 0xab, 0x8e, 0x95, 0x66, 0xc8, 0xe5, 0xcc, 0x80, 0xa3, 0xbd, 0x16,
    211     0xa7, 0x79, 0x19, 0x39, 0x61, 0x3d, 0xff, 0x37, 0xca, 0x9f, 0x97, 0x05,
    212     0xc7, 0xcb, 0xf0, 0xea, 0xaf, 0x64, 0x07, 0xc0, 0xed, 0x2a, 0x98, 0xa4,
    213     0xaf, 0x04, 0x6f, 0xf2, 0xc9, 0xb2, 0x73, 0x9a, 0x56, 0x85, 0x43, 0x64,
    214     0x5f, 0xaa, 0xb7, 0xff, 0x31, 0x4c, 0x2e, 0x6c, 0x17, 0xcf, 0xe5, 0xbe,
    215     0x7f, 0x7e, 0xad, 0xf5, 0x6f, 0x84, 0x50, 0x20, 0x29, 0xb3, 0x57, 0xe7,
    216     0xb1, 0xdc, 0x2c, 0x95, 0x48, 0xfe, 0xb0, 0xc1, 0x92, 0xda, 0xc5, 0x58,
    217     0x95, 0xb0, 0x1a, 0x3a, 0x05, 0x71, 0x3c, 0x6d, 0x20, 0x01, 0x4c, 0xa9,
    218     0xe4, 0x38, 0x08, 0x65, 0xb4, 0xbd, 0x86, 0x76, 0xbd, 0xad, 0x25, 0x06,
    219     0x74, 0x0b, 0xca, 0x95, 0x27, 0x0c, 0x13, 0x08, 0x7e, 0x30, 0xcf, 0xf6,
    220     0xb5, 0xc1, 0x2a, 0x08, 0xfc, 0x4b, 0xc6, 0xb5, 0x2f, 0x23, 0x27, 0x32,
    221     0x89, 0xdb, 0x0e, 0x4a,
    222   };
    223   static const unsigned char signature_data_2[] = {
    224     0x6d, 0x7d, 0x22, 0x8c, 0x85, 0xc4, 0x8a, 0x80, 0x05, 0xe4, 0x3c, 0xaf,
    225     0x10, 0x3b, 0xe3, 0x51, 0xb1, 0x86, 0x52, 0x63, 0xb6, 0x17, 0x33, 0xbd,
    226     0x1b, 0x1e, 0xc4, 0x50, 0x10, 0xfc, 0xcc, 0xea, 0x6b, 0x11, 0xeb, 0x6d,
    227     0x5e, 0x00, 0xe7, 0xf3, 0x67, 0x99, 0x74, 0x53, 0x12, 0x8f, 0xe4, 0x3e,
    228     0x20, 0x17, 0x8e, 0x83, 0xe6, 0xdc, 0x83, 0x91, 0x0e, 0xf3, 0x69, 0x22,
    229     0x95, 0x14, 0xdf, 0xc1, 0xda, 0xb5, 0xdb, 0x6a, 0x1a, 0xb4, 0x4f, 0x26,
    230     0xd0, 0x32, 0x1d, 0x73, 0x95, 0x1f, 0x39, 0x1d, 0x00, 0xcb, 0xc3, 0x92,
    231     0x49, 0x53, 0xcb, 0x5c, 0x36, 0x70, 0x19, 0xd9, 0x64, 0x36, 0xda, 0xfb,
    232     0x20, 0xe5, 0x47, 0xd9, 0x08, 0xc6, 0x5a, 0x9e, 0x87, 0x1a, 0xdb, 0x11,
    233     0x7b, 0x17, 0xfc, 0x53, 0x7b, 0xc1, 0xa0, 0xc0, 0x33, 0xcf, 0x96, 0xba,
    234     0x03, 0x79, 0x8e, 0xc6, 0x05, 0xd2, 0xb7, 0xa2, 0xe2, 0xc1, 0x67, 0xb7,
    235     0x6a, 0xeb, 0xb1, 0x40, 0xbb, 0x7d, 0x57, 0xcb, 0xc2, 0x60, 0x9f, 0xf1,
    236     0x72, 0xe5, 0xad, 0xce, 0x95, 0x45, 0x7c, 0xbc, 0x75, 0x81, 0x45, 0x19,
    237     0xe1, 0xa7, 0x2f, 0x05, 0x52, 0xeb, 0xed, 0xdd, 0x19, 0xd9, 0x1a, 0xc9,
    238     0x5a, 0x06, 0x8e, 0x29, 0x54, 0xb5, 0x4f, 0x80, 0xaa, 0x36, 0x36, 0xc0,
    239     0xff, 0x64, 0xac, 0xe8, 0x0f, 0x99, 0x35, 0x5e, 0xc6, 0x72, 0x1f, 0x8c,
    240     0xc4, 0x2b, 0x7d, 0xc1, 0xfb, 0xf0, 0x12, 0x61, 0xb1, 0x18, 0x65, 0xdd,
    241     0xc2, 0x38, 0x92, 0xba, 0x84, 0xf8, 0xc8, 0x5e, 0x17, 0x63, 0xe0, 0x9c,
    242     0x2c, 0xe6, 0x70, 0x71, 0xdc, 0xe5, 0xc1, 0xea, 0xb3, 0x9a, 0xb6, 0x91,
    243     0xdc, 0xc5, 0x56, 0x84, 0x8a, 0x31, 0x31, 0x23, 0x61, 0x94, 0x7e, 0x01,
    244     0x22, 0x49, 0xf3, 0xcb, 0x0e, 0x31, 0x03, 0x04, 0x1b, 0x14, 0x43, 0x7c,
    245     0xad, 0x42, 0xe5, 0x55,
    246   };
    247 
    248   scoped_ptr<ProofVerifier> verifier(
    249       CryptoTestUtils::ProofVerifierForTesting());
    250 
    251   const string server_config = "server config bytes";
    252   const string hostname = "test.example.com";
    253   CertVerifyResult cert_verify_result;
    254 
    255   vector<string> certs(2);
    256   certs[0] = PEMCertFileToDER("quic_test.example.com.crt");
    257   certs[1] = PEMCertFileToDER("quic_intermediate.crt");
    258 
    259   // Signatures are nondeterministic, so we test multiple signatures on the
    260   // same server_config.
    261   vector<string> signatures(3);
    262   signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
    263                        sizeof(signature_data_0));
    264   signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
    265                        sizeof(signature_data_1));
    266   signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
    267                        sizeof(signature_data_2));
    268 
    269   for (size_t i = 0; i < signatures.size(); i++) {
    270     const string& signature = signatures[i];
    271 
    272     RunVerification(
    273         verifier.get(), hostname, server_config, certs, signature, true);
    274     RunVerification(
    275         verifier.get(), "foo.com", server_config, certs, signature, false);
    276     RunVerification(
    277         verifier.get(), hostname, server_config.substr(1, string::npos),
    278         certs, signature, false);
    279 
    280     const string corrupt_signature = "1" + signature;
    281     RunVerification(
    282         verifier.get(), hostname, server_config, certs, corrupt_signature,
    283         false);
    284 
    285     vector<string> wrong_certs;
    286     for (size_t i = 1; i < certs.size(); i++) {
    287       wrong_certs.push_back(certs[i]);
    288     }
    289     RunVerification(verifier.get(), hostname, server_config, wrong_certs,
    290                     signature, false);
    291   }
    292 }
    293 
    294 // A known answer test that allows us to test ProofVerifier without a working
    295 // ProofSource.
    296 TEST(ProofTest, VerifyECDSAKnownAnswerTest) {
    297   // Disable this test on platforms that do not support ECDSA certificates.
    298 #if defined(OS_WIN)
    299   if (base::win::GetVersion() < base::win::VERSION_VISTA)
    300     return;
    301 #endif
    302 
    303   // These sample signatures were generated by running the Proof.Verify test
    304   // (modified to use ECDSA for signing proofs) and dumping the bytes of the
    305   // |signature| output of ProofSource::GetProof().
    306   static const unsigned char signature_data_0[] = {
    307     0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0xc4, 0x7d, 0x08, 0xd1, 0x49, 0x19,
    308     0x6c, 0xd1, 0x7c, 0xb9, 0x25, 0xe0, 0xe3, 0xbd, 0x6a, 0x5c, 0xd7, 0xaa,
    309     0x0c, 0xdc, 0x4f, 0x8e, 0xeb, 0xde, 0xbf, 0x32, 0xf8, 0xd1, 0x84, 0x95,
    310     0x97, 0x02, 0x20, 0x29, 0x3d, 0x49, 0x22, 0x73, 0xed, 0x8b, 0xde, 0x3d,
    311     0xc2, 0xa4, 0x20, 0xcc, 0xe7, 0xc8, 0x2a, 0x85, 0x20, 0x9b, 0x5b, 0xda,
    312     0xcd, 0x58, 0x23, 0xbe, 0x89, 0x73, 0x31, 0x87, 0x51, 0xd1, 0x01,
    313   };
    314   static const unsigned char signature_data_1[] = {
    315     0x30, 0x46, 0x02, 0x21, 0x00, 0xec, 0xdf, 0x69, 0xc8, 0x24, 0x59, 0x93,
    316     0xda, 0x49, 0xee, 0x37, 0x28, 0xaf, 0xeb, 0x0e, 0x2f, 0x80, 0x17, 0x4b,
    317     0x3b, 0xf6, 0x54, 0xcd, 0x3b, 0x86, 0xc5, 0x98, 0x0d, 0xff, 0xc6, 0xb1,
    318     0xe7, 0x02, 0x21, 0x00, 0xe1, 0x36, 0x8c, 0xc0, 0xf4, 0x50, 0x5f, 0xba,
    319     0xfb, 0xe2, 0xff, 0x1d, 0x5d, 0x64, 0xe4, 0x07, 0xbb, 0x5a, 0x4b, 0x19,
    320     0xb6, 0x39, 0x7a, 0xc4, 0x12, 0xc6, 0xe5, 0x42, 0xc8, 0x78, 0x33, 0xcd,
    321   };
    322   static const unsigned char signature_data_2[] = {
    323     0x30, 0x45, 0x02, 0x20, 0x09, 0x51, 0xe9, 0xde, 0xdb, 0x01, 0xfd, 0xb4,
    324     0xd8, 0x20, 0xbb, 0xad, 0x41, 0xe3, 0xaa, 0xe7, 0xa3, 0xc3, 0x32, 0x10,
    325     0x9d, 0xfa, 0x37, 0xce, 0x17, 0xd1, 0x29, 0xf9, 0xd4, 0x1d, 0x0d, 0x19,
    326     0x02, 0x21, 0x00, 0xc6, 0x20, 0xd4, 0x28, 0xf9, 0x70, 0xb5, 0xb4, 0xff,
    327     0x4a, 0x35, 0xba, 0xa0, 0xf2, 0x8e, 0x00, 0xf7, 0xcb, 0x43, 0xaf, 0x2d,
    328     0x1f, 0xce, 0x92, 0x05, 0xca, 0x29, 0xfe, 0xd2, 0x8f, 0xd9, 0x31,
    329   };
    330 
    331   scoped_ptr<ProofVerifier> verifier(
    332       CryptoTestUtils::ProofVerifierForTesting());
    333 
    334   const string server_config = "server config bytes";
    335   const string hostname = "test.example.com";
    336   CertVerifyResult cert_verify_result;
    337 
    338   vector<string> certs(2);
    339   certs[0] = PEMCertFileToDER("quic_test_ecc.example.com.crt");
    340   certs[1] = PEMCertFileToDER("quic_intermediate.crt");
    341 
    342   // Signatures are nondeterministic, so we test multiple signatures on the
    343   // same server_config.
    344   vector<string> signatures(3);
    345   signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
    346                        sizeof(signature_data_0));
    347   signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
    348                        sizeof(signature_data_1));
    349   signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
    350                        sizeof(signature_data_2));
    351 
    352   for (size_t i = 0; i < signatures.size(); i++) {
    353     const string& signature = signatures[i];
    354 
    355     RunVerification(
    356         verifier.get(), hostname, server_config, certs, signature, true);
    357     RunVerification(
    358         verifier.get(), "foo.com", server_config, certs, signature, false);
    359     RunVerification(
    360         verifier.get(), hostname, server_config.substr(1, string::npos),
    361         certs, signature, false);
    362 
    363     // An ECDSA signature is DER-encoded. Corrupt the last byte so that the
    364     // signature can still be DER-decoded correctly.
    365     string corrupt_signature = signature;
    366     corrupt_signature[corrupt_signature.size() - 1] += 1;
    367     RunVerification(
    368         verifier.get(), hostname, server_config, certs, corrupt_signature,
    369         false);
    370 
    371     // Prepending a "1" makes the DER invalid.
    372     const string bad_der_signature1 = "1" + signature;
    373     RunVerification(
    374         verifier.get(), hostname, server_config, certs, bad_der_signature1,
    375         false);
    376 
    377     vector<string> wrong_certs;
    378     for (size_t i = 1; i < certs.size(); i++) {
    379       wrong_certs.push_back(certs[i]);
    380     }
    381     RunVerification(
    382         verifier.get(), hostname, server_config, wrong_certs, signature,
    383         false);
    384   }
    385 }
    386 
    387 }  // namespace test
    388 }  // namespace net
    389