| Index: net/quic/test_tools/crypto_test_utils.cc
|
| diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc
|
| deleted file mode 100644
|
| index d6238bdd7ce0f793974106c5995ec89ef019a643..0000000000000000000000000000000000000000
|
| --- a/net/quic/test_tools/crypto_test_utils.cc
|
| +++ /dev/null
|
| @@ -1,633 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/quic/test_tools/crypto_test_utils.h"
|
| -
|
| -#include "net/quic/crypto/channel_id.h"
|
| -#include "net/quic/crypto/common_cert_set.h"
|
| -#include "net/quic/crypto/crypto_handshake.h"
|
| -#include "net/quic/crypto/quic_crypto_server_config.h"
|
| -#include "net/quic/crypto/quic_decrypter.h"
|
| -#include "net/quic/crypto/quic_encrypter.h"
|
| -#include "net/quic/crypto/quic_random.h"
|
| -#include "net/quic/quic_clock.h"
|
| -#include "net/quic/quic_crypto_client_stream.h"
|
| -#include "net/quic/quic_crypto_server_stream.h"
|
| -#include "net/quic/quic_crypto_stream.h"
|
| -#include "net/quic/quic_server_id.h"
|
| -#include "net/quic/test_tools/quic_connection_peer.h"
|
| -#include "net/quic/test_tools/quic_test_utils.h"
|
| -#include "net/quic/test_tools/simple_quic_framer.h"
|
| -
|
| -using base::StringPiece;
|
| -using std::make_pair;
|
| -using std::pair;
|
| -using std::string;
|
| -using std::vector;
|
| -
|
| -namespace net {
|
| -namespace test {
|
| -
|
| -namespace {
|
| -
|
| -const char kServerHostname[] = "test.example.com";
|
| -const uint16 kServerPort = 80;
|
| -
|
| -// CryptoFramerVisitor is a framer visitor that records handshake messages.
|
| -class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
|
| - public:
|
| - CryptoFramerVisitor()
|
| - : error_(false) {
|
| - }
|
| -
|
| - void OnError(CryptoFramer* framer) override { error_ = true; }
|
| -
|
| - void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
|
| - messages_.push_back(message);
|
| - }
|
| -
|
| - bool error() const {
|
| - return error_;
|
| - }
|
| -
|
| - const vector<CryptoHandshakeMessage>& messages() const {
|
| - return messages_;
|
| - }
|
| -
|
| - private:
|
| - bool error_;
|
| - vector<CryptoHandshakeMessage> messages_;
|
| -};
|
| -
|
| -// MovePackets parses crypto handshake messages from packet number
|
| -// |*inout_packet_index| through to the last packet (or until a packet fails to
|
| -// decrypt) and has |dest_stream| process them. |*inout_packet_index| is updated
|
| -// with an index one greater than the last packet processed.
|
| -void MovePackets(PacketSavingConnection* source_conn,
|
| - size_t *inout_packet_index,
|
| - QuicCryptoStream* dest_stream,
|
| - PacketSavingConnection* dest_conn) {
|
| - SimpleQuicFramer framer(source_conn->supported_versions());
|
| - CryptoFramer crypto_framer;
|
| - CryptoFramerVisitor crypto_visitor;
|
| -
|
| - // In order to properly test the code we need to perform encryption and
|
| - // decryption so that the crypters latch when expected. The crypters are in
|
| - // |dest_conn|, but we don't want to try and use them there. Instead we swap
|
| - // them into |framer|, perform the decryption with them, and then swap them
|
| - // back.
|
| - QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
|
| -
|
| - crypto_framer.set_visitor(&crypto_visitor);
|
| -
|
| - size_t index = *inout_packet_index;
|
| - for (; index < source_conn->encrypted_packets_.size(); index++) {
|
| - if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
|
| - // The framer will be unable to decrypt forward-secure packets sent after
|
| - // the handshake is complete. Don't treat them as handshake packets.
|
| - break;
|
| - }
|
| -
|
| - for (vector<QuicStreamFrame>::const_iterator
|
| - i = framer.stream_frames().begin();
|
| - i != framer.stream_frames().end(); ++i) {
|
| - scoped_ptr<string> frame_data(i->GetDataAsString());
|
| - ASSERT_TRUE(crypto_framer.ProcessInput(*frame_data));
|
| - ASSERT_FALSE(crypto_visitor.error());
|
| - }
|
| - }
|
| - *inout_packet_index = index;
|
| -
|
| - QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
|
| -
|
| - ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
|
| -
|
| - for (vector<CryptoHandshakeMessage>::const_iterator
|
| - i = crypto_visitor.messages().begin();
|
| - i != crypto_visitor.messages().end(); ++i) {
|
| - dest_stream->OnHandshakeMessage(*i);
|
| - }
|
| -}
|
| -
|
| -// HexChar parses |c| as a hex character. If valid, it sets |*value| to the
|
| -// value of the hex character and returns true. Otherwise it returns false.
|
| -bool HexChar(char c, uint8* value) {
|
| - if (c >= '0' && c <= '9') {
|
| - *value = c - '0';
|
| - return true;
|
| - }
|
| - if (c >= 'a' && c <= 'f') {
|
| - *value = c - 'a' + 10;
|
| - return true;
|
| - }
|
| - if (c >= 'A' && c <= 'F') {
|
| - *value = c - 'A' + 10;
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// A ChannelIDSource that works in asynchronous mode unless the |callback|
|
| -// argument to GetChannelIDKey is nullptr.
|
| -class AsyncTestChannelIDSource : public ChannelIDSource,
|
| - public CryptoTestUtils::CallbackSource {
|
| - public:
|
| - // Takes ownership of |sync_source|, a synchronous ChannelIDSource.
|
| - explicit AsyncTestChannelIDSource(ChannelIDSource* sync_source)
|
| - : sync_source_(sync_source) {}
|
| - ~AsyncTestChannelIDSource() override {}
|
| -
|
| - // ChannelIDSource implementation.
|
| - QuicAsyncStatus GetChannelIDKey(const string& hostname,
|
| - scoped_ptr<ChannelIDKey>* channel_id_key,
|
| - ChannelIDSourceCallback* callback) override {
|
| - // Synchronous mode.
|
| - if (!callback) {
|
| - return sync_source_->GetChannelIDKey(hostname, channel_id_key, nullptr);
|
| - }
|
| -
|
| - // Asynchronous mode.
|
| - QuicAsyncStatus status =
|
| - sync_source_->GetChannelIDKey(hostname, &channel_id_key_, nullptr);
|
| - if (status != QUIC_SUCCESS) {
|
| - return QUIC_FAILURE;
|
| - }
|
| - callback_.reset(callback);
|
| - return QUIC_PENDING;
|
| - }
|
| -
|
| - // CallbackSource implementation.
|
| - void RunPendingCallbacks() override {
|
| - if (callback_.get()) {
|
| - callback_->Run(&channel_id_key_);
|
| - callback_.reset();
|
| - }
|
| - }
|
| -
|
| - private:
|
| - scoped_ptr<ChannelIDSource> sync_source_;
|
| - scoped_ptr<ChannelIDSourceCallback> callback_;
|
| - scoped_ptr<ChannelIDKey> channel_id_key_;
|
| -};
|
| -
|
| -} // anonymous namespace
|
| -
|
| -CryptoTestUtils::FakeClientOptions::FakeClientOptions()
|
| - : dont_verify_certs(false),
|
| - channel_id_enabled(false),
|
| - channel_id_source_async(false) {
|
| -}
|
| -
|
| -// static
|
| -int CryptoTestUtils::HandshakeWithFakeServer(
|
| - PacketSavingConnection* client_conn,
|
| - QuicCryptoClientStream* client) {
|
| - PacketSavingConnection* server_conn =
|
| - new PacketSavingConnection(true, client_conn->supported_versions());
|
| - TestSession server_session(server_conn, DefaultQuicConfig());
|
| - server_session.InitializeSession();
|
| - QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING,
|
| - QuicRandom::GetInstance());
|
| -
|
| - SetupCryptoServerConfigForTest(
|
| - server_session.connection()->clock(),
|
| - server_session.connection()->random_generator(),
|
| - server_session.config(), &crypto_config);
|
| -
|
| - QuicCryptoServerStream server(crypto_config, &server_session);
|
| - server_session.SetCryptoStream(&server);
|
| -
|
| - // The client's handshake must have been started already.
|
| - CHECK_NE(0u, client_conn->encrypted_packets_.size());
|
| -
|
| - CommunicateHandshakeMessages(client_conn, client, server_conn, &server);
|
| -
|
| - CompareClientAndServerKeys(client, &server);
|
| -
|
| - return client->num_sent_client_hellos();
|
| -}
|
| -
|
| -// static
|
| -int CryptoTestUtils::HandshakeWithFakeClient(
|
| - PacketSavingConnection* server_conn,
|
| - QuicCryptoServerStream* server,
|
| - const FakeClientOptions& options) {
|
| - PacketSavingConnection* client_conn = new PacketSavingConnection(false);
|
| - // Advance the time, because timers do not like uninitialized times.
|
| - client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
|
| - TestClientSession client_session(client_conn, DefaultQuicConfig());
|
| - QuicCryptoClientConfig crypto_config;
|
| -
|
| - if (!options.dont_verify_certs) {
|
| - // TODO(wtc): replace this with ProofVerifierForTesting() when we have
|
| - // a working ProofSourceForTesting().
|
| - crypto_config.SetProofVerifier(FakeProofVerifierForTesting());
|
| - }
|
| - bool is_https = false;
|
| - AsyncTestChannelIDSource* async_channel_id_source = nullptr;
|
| - if (options.channel_id_enabled) {
|
| - is_https = true;
|
| -
|
| - ChannelIDSource* source = ChannelIDSourceForTesting();
|
| - if (options.channel_id_source_async) {
|
| - async_channel_id_source = new AsyncTestChannelIDSource(source);
|
| - source = async_channel_id_source;
|
| - }
|
| - crypto_config.SetChannelIDSource(source);
|
| - }
|
| - QuicServerId server_id(kServerHostname, kServerPort, is_https,
|
| - PRIVACY_MODE_DISABLED);
|
| - QuicCryptoClientStream client(server_id, &client_session,
|
| - ProofVerifyContextForTesting(),
|
| - &crypto_config);
|
| - client_session.SetCryptoStream(&client);
|
| -
|
| - client.CryptoConnect();
|
| - CHECK_EQ(1u, client_conn->encrypted_packets_.size());
|
| -
|
| - CommunicateHandshakeMessagesAndRunCallbacks(
|
| - client_conn, &client, server_conn, server, async_channel_id_source);
|
| -
|
| - CompareClientAndServerKeys(&client, server);
|
| -
|
| - if (options.channel_id_enabled) {
|
| - scoped_ptr<ChannelIDKey> channel_id_key;
|
| - QuicAsyncStatus status = crypto_config.channel_id_source()->GetChannelIDKey(
|
| - kServerHostname, &channel_id_key, nullptr);
|
| - EXPECT_EQ(QUIC_SUCCESS, status);
|
| - EXPECT_EQ(channel_id_key->SerializeKey(),
|
| - server->crypto_negotiated_params().channel_id);
|
| - EXPECT_EQ(options.channel_id_source_async,
|
| - client.WasChannelIDSourceCallbackRun());
|
| - }
|
| -
|
| - return client.num_sent_client_hellos();
|
| -}
|
| -
|
| -// static
|
| -void CryptoTestUtils::SetupCryptoServerConfigForTest(
|
| - const QuicClock* clock,
|
| - QuicRandom* rand,
|
| - QuicConfig* config,
|
| - QuicCryptoServerConfig* crypto_config) {
|
| - QuicCryptoServerConfig::ConfigOptions options;
|
| - options.channel_id_enabled = true;
|
| - scoped_ptr<CryptoHandshakeMessage> scfg(
|
| - crypto_config->AddDefaultConfig(rand, clock, options));
|
| -}
|
| -
|
| -// static
|
| -void CryptoTestUtils::CommunicateHandshakeMessages(
|
| - PacketSavingConnection* a_conn,
|
| - QuicCryptoStream* a,
|
| - PacketSavingConnection* b_conn,
|
| - QuicCryptoStream* b) {
|
| - CommunicateHandshakeMessagesAndRunCallbacks(a_conn, a, b_conn, b, nullptr);
|
| -}
|
| -
|
| -// static
|
| -void CryptoTestUtils::CommunicateHandshakeMessagesAndRunCallbacks(
|
| - PacketSavingConnection* a_conn,
|
| - QuicCryptoStream* a,
|
| - PacketSavingConnection* b_conn,
|
| - QuicCryptoStream* b,
|
| - CallbackSource* callback_source) {
|
| - size_t a_i = 0, b_i = 0;
|
| - while (!a->handshake_confirmed()) {
|
| - ASSERT_GT(a_conn->encrypted_packets_.size(), a_i);
|
| - VLOG(1) << "Processing " << a_conn->encrypted_packets_.size() - a_i
|
| - << " packets a->b";
|
| - MovePackets(a_conn, &a_i, b, b_conn);
|
| - if (callback_source) {
|
| - callback_source->RunPendingCallbacks();
|
| - }
|
| -
|
| - ASSERT_GT(b_conn->encrypted_packets_.size(), b_i);
|
| - VLOG(1) << "Processing " << b_conn->encrypted_packets_.size() - b_i
|
| - << " packets b->a";
|
| - MovePackets(b_conn, &b_i, a, a_conn);
|
| - if (callback_source) {
|
| - callback_source->RunPendingCallbacks();
|
| - }
|
| - }
|
| -}
|
| -
|
| -// static
|
| -pair<size_t, size_t> CryptoTestUtils::AdvanceHandshake(
|
| - PacketSavingConnection* a_conn,
|
| - QuicCryptoStream* a,
|
| - size_t a_i,
|
| - PacketSavingConnection* b_conn,
|
| - QuicCryptoStream* b,
|
| - size_t b_i) {
|
| - VLOG(1) << "Processing " << a_conn->encrypted_packets_.size() - a_i
|
| - << " packets a->b";
|
| - MovePackets(a_conn, &a_i, b, b_conn);
|
| -
|
| - VLOG(1) << "Processing " << b_conn->encrypted_packets_.size() - b_i
|
| - << " packets b->a";
|
| - if (b_conn->encrypted_packets_.size() - b_i == 2) {
|
| - VLOG(1) << "here";
|
| - }
|
| - MovePackets(b_conn, &b_i, a, a_conn);
|
| -
|
| - return std::make_pair(a_i, b_i);
|
| -}
|
| -
|
| -// static
|
| -string CryptoTestUtils::GetValueForTag(const CryptoHandshakeMessage& message,
|
| - QuicTag tag) {
|
| - QuicTagValueMap::const_iterator it = message.tag_value_map().find(tag);
|
| - if (it == message.tag_value_map().end()) {
|
| - return string();
|
| - }
|
| - return it->second;
|
| -}
|
| -
|
| -class MockCommonCertSets : public CommonCertSets {
|
| - public:
|
| - MockCommonCertSets(StringPiece cert, uint64 hash, uint32 index)
|
| - : cert_(cert.as_string()),
|
| - hash_(hash),
|
| - index_(index) {
|
| - }
|
| -
|
| - StringPiece GetCommonHashes() const override {
|
| - CHECK(false) << "not implemented";
|
| - return StringPiece();
|
| - }
|
| -
|
| - StringPiece GetCert(uint64 hash, uint32 index) const override {
|
| - if (hash == hash_ && index == index_) {
|
| - return cert_;
|
| - }
|
| - return StringPiece();
|
| - }
|
| -
|
| - bool MatchCert(StringPiece cert,
|
| - StringPiece common_set_hashes,
|
| - uint64* out_hash,
|
| - uint32* out_index) const override {
|
| - if (cert != cert_) {
|
| - return false;
|
| - }
|
| -
|
| - if (common_set_hashes.size() % sizeof(uint64) != 0) {
|
| - return false;
|
| - }
|
| - bool client_has_set = false;
|
| - for (size_t i = 0; i < common_set_hashes.size(); i += sizeof(uint64)) {
|
| - uint64 hash;
|
| - memcpy(&hash, common_set_hashes.data() + i, sizeof(hash));
|
| - if (hash == hash_) {
|
| - client_has_set = true;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - if (!client_has_set) {
|
| - return false;
|
| - }
|
| -
|
| - *out_hash = hash_;
|
| - *out_index = index_;
|
| - return true;
|
| - }
|
| -
|
| - private:
|
| - const string cert_;
|
| - const uint64 hash_;
|
| - const uint32 index_;
|
| -};
|
| -
|
| -CommonCertSets* CryptoTestUtils::MockCommonCertSets(StringPiece cert,
|
| - uint64 hash,
|
| - uint32 index) {
|
| - return new class MockCommonCertSets(cert, hash, index);
|
| -}
|
| -
|
| -void CryptoTestUtils::CompareClientAndServerKeys(
|
| - QuicCryptoClientStream* client,
|
| - QuicCryptoServerStream* server) {
|
| - const QuicEncrypter* client_encrypter(
|
| - client->session()->connection()->encrypter(ENCRYPTION_INITIAL));
|
| - const QuicDecrypter* client_decrypter(
|
| - client->session()->connection()->decrypter());
|
| - const QuicEncrypter* client_forward_secure_encrypter(
|
| - client->session()->connection()->encrypter(ENCRYPTION_FORWARD_SECURE));
|
| - const QuicDecrypter* client_forward_secure_decrypter(
|
| - client->session()->connection()->alternative_decrypter());
|
| - const QuicEncrypter* server_encrypter(
|
| - server->session()->connection()->encrypter(ENCRYPTION_INITIAL));
|
| - const QuicDecrypter* server_decrypter(
|
| - server->session()->connection()->decrypter());
|
| - const QuicEncrypter* server_forward_secure_encrypter(
|
| - server->session()->connection()->encrypter(ENCRYPTION_FORWARD_SECURE));
|
| - const QuicDecrypter* server_forward_secure_decrypter(
|
| - server->session()->connection()->alternative_decrypter());
|
| -
|
| - StringPiece client_encrypter_key = client_encrypter->GetKey();
|
| - StringPiece client_encrypter_iv = client_encrypter->GetNoncePrefix();
|
| - StringPiece client_decrypter_key = client_decrypter->GetKey();
|
| - StringPiece client_decrypter_iv = client_decrypter->GetNoncePrefix();
|
| - StringPiece client_forward_secure_encrypter_key =
|
| - client_forward_secure_encrypter->GetKey();
|
| - StringPiece client_forward_secure_encrypter_iv =
|
| - client_forward_secure_encrypter->GetNoncePrefix();
|
| - StringPiece client_forward_secure_decrypter_key =
|
| - client_forward_secure_decrypter->GetKey();
|
| - StringPiece client_forward_secure_decrypter_iv =
|
| - client_forward_secure_decrypter->GetNoncePrefix();
|
| - StringPiece server_encrypter_key = server_encrypter->GetKey();
|
| - StringPiece server_encrypter_iv = server_encrypter->GetNoncePrefix();
|
| - StringPiece server_decrypter_key = server_decrypter->GetKey();
|
| - StringPiece server_decrypter_iv = server_decrypter->GetNoncePrefix();
|
| - StringPiece server_forward_secure_encrypter_key =
|
| - server_forward_secure_encrypter->GetKey();
|
| - StringPiece server_forward_secure_encrypter_iv =
|
| - server_forward_secure_encrypter->GetNoncePrefix();
|
| - StringPiece server_forward_secure_decrypter_key =
|
| - server_forward_secure_decrypter->GetKey();
|
| - StringPiece server_forward_secure_decrypter_iv =
|
| - server_forward_secure_decrypter->GetNoncePrefix();
|
| -
|
| - StringPiece client_subkey_secret =
|
| - client->crypto_negotiated_params().subkey_secret;
|
| - StringPiece server_subkey_secret =
|
| - server->crypto_negotiated_params().subkey_secret;
|
| -
|
| -
|
| - const char kSampleLabel[] = "label";
|
| - const char kSampleContext[] = "context";
|
| - const size_t kSampleOutputLength = 32;
|
| - string client_key_extraction;
|
| - string server_key_extraction;
|
| - EXPECT_TRUE(client->ExportKeyingMaterial(kSampleLabel,
|
| - kSampleContext,
|
| - kSampleOutputLength,
|
| - &client_key_extraction));
|
| - EXPECT_TRUE(server->ExportKeyingMaterial(kSampleLabel,
|
| - kSampleContext,
|
| - kSampleOutputLength,
|
| - &server_key_extraction));
|
| -
|
| - CompareCharArraysWithHexError("client write key",
|
| - client_encrypter_key.data(),
|
| - client_encrypter_key.length(),
|
| - server_decrypter_key.data(),
|
| - server_decrypter_key.length());
|
| - CompareCharArraysWithHexError("client write IV",
|
| - client_encrypter_iv.data(),
|
| - client_encrypter_iv.length(),
|
| - server_decrypter_iv.data(),
|
| - server_decrypter_iv.length());
|
| - CompareCharArraysWithHexError("server write key",
|
| - server_encrypter_key.data(),
|
| - server_encrypter_key.length(),
|
| - client_decrypter_key.data(),
|
| - client_decrypter_key.length());
|
| - CompareCharArraysWithHexError("server write IV",
|
| - server_encrypter_iv.data(),
|
| - server_encrypter_iv.length(),
|
| - client_decrypter_iv.data(),
|
| - client_decrypter_iv.length());
|
| - CompareCharArraysWithHexError("client forward secure write key",
|
| - client_forward_secure_encrypter_key.data(),
|
| - client_forward_secure_encrypter_key.length(),
|
| - server_forward_secure_decrypter_key.data(),
|
| - server_forward_secure_decrypter_key.length());
|
| - CompareCharArraysWithHexError("client forward secure write IV",
|
| - client_forward_secure_encrypter_iv.data(),
|
| - client_forward_secure_encrypter_iv.length(),
|
| - server_forward_secure_decrypter_iv.data(),
|
| - server_forward_secure_decrypter_iv.length());
|
| - CompareCharArraysWithHexError("server forward secure write key",
|
| - server_forward_secure_encrypter_key.data(),
|
| - server_forward_secure_encrypter_key.length(),
|
| - client_forward_secure_decrypter_key.data(),
|
| - client_forward_secure_decrypter_key.length());
|
| - CompareCharArraysWithHexError("server forward secure write IV",
|
| - server_forward_secure_encrypter_iv.data(),
|
| - server_forward_secure_encrypter_iv.length(),
|
| - client_forward_secure_decrypter_iv.data(),
|
| - client_forward_secure_decrypter_iv.length());
|
| - CompareCharArraysWithHexError("subkey secret",
|
| - client_subkey_secret.data(),
|
| - client_subkey_secret.length(),
|
| - server_subkey_secret.data(),
|
| - server_subkey_secret.length());
|
| - CompareCharArraysWithHexError("sample key extraction",
|
| - client_key_extraction.data(),
|
| - client_key_extraction.length(),
|
| - server_key_extraction.data(),
|
| - server_key_extraction.length());
|
| -}
|
| -
|
| -// static
|
| -QuicTag CryptoTestUtils::ParseTag(const char* tagstr) {
|
| - const size_t len = strlen(tagstr);
|
| - CHECK_NE(0u, len);
|
| -
|
| - QuicTag tag = 0;
|
| -
|
| - if (tagstr[0] == '#') {
|
| - CHECK_EQ(static_cast<size_t>(1 + 2*4), len);
|
| - tagstr++;
|
| -
|
| - for (size_t i = 0; i < 8; i++) {
|
| - tag <<= 4;
|
| -
|
| - uint8 v = 0;
|
| - CHECK(HexChar(tagstr[i], &v));
|
| - tag |= v;
|
| - }
|
| -
|
| - return tag;
|
| - }
|
| -
|
| - CHECK_LE(len, 4u);
|
| - for (size_t i = 0; i < 4; i++) {
|
| - tag >>= 8;
|
| - if (i < len) {
|
| - tag |= static_cast<uint32>(tagstr[i]) << 24;
|
| - }
|
| - }
|
| -
|
| - return tag;
|
| -}
|
| -
|
| -// static
|
| -CryptoHandshakeMessage CryptoTestUtils::Message(const char* message_tag, ...) {
|
| - va_list ap;
|
| - va_start(ap, message_tag);
|
| -
|
| - CryptoHandshakeMessage message = BuildMessage(message_tag, ap);
|
| - va_end(ap);
|
| - return message;
|
| -}
|
| -
|
| -// static
|
| -CryptoHandshakeMessage CryptoTestUtils::BuildMessage(const char* message_tag,
|
| - va_list ap) {
|
| - CryptoHandshakeMessage msg;
|
| - msg.set_tag(ParseTag(message_tag));
|
| -
|
| - for (;;) {
|
| - const char* tagstr = va_arg(ap, const char*);
|
| - if (tagstr == nullptr) {
|
| - break;
|
| - }
|
| -
|
| - if (tagstr[0] == '$') {
|
| - // Special value.
|
| - const char* const special = tagstr + 1;
|
| - if (strcmp(special, "padding") == 0) {
|
| - const int min_bytes = va_arg(ap, int);
|
| - msg.set_minimum_size(min_bytes);
|
| - } else {
|
| - CHECK(false) << "Unknown special value: " << special;
|
| - }
|
| -
|
| - continue;
|
| - }
|
| -
|
| - const QuicTag tag = ParseTag(tagstr);
|
| - const char* valuestr = va_arg(ap, const char*);
|
| -
|
| - size_t len = strlen(valuestr);
|
| - if (len > 0 && valuestr[0] == '#') {
|
| - valuestr++;
|
| - len--;
|
| -
|
| - CHECK_EQ(0u, len % 2);
|
| - scoped_ptr<uint8[]> buf(new uint8[len/2]);
|
| -
|
| - for (size_t i = 0; i < len/2; i++) {
|
| - uint8 v = 0;
|
| - CHECK(HexChar(valuestr[i*2], &v));
|
| - buf[i] = v << 4;
|
| - CHECK(HexChar(valuestr[i*2 + 1], &v));
|
| - buf[i] |= v;
|
| - }
|
| -
|
| - msg.SetStringPiece(
|
| - tag, StringPiece(reinterpret_cast<char*>(buf.get()), len/2));
|
| - continue;
|
| - }
|
| -
|
| - msg.SetStringPiece(tag, valuestr);
|
| - }
|
| -
|
| - // The CryptoHandshakeMessage needs to be serialized and parsed to ensure
|
| - // that any padding is included.
|
| - scoped_ptr<QuicData> bytes(CryptoFramer::ConstructHandshakeMessage(msg));
|
| - scoped_ptr<CryptoHandshakeMessage> parsed(
|
| - CryptoFramer::ParseMessage(bytes->AsStringPiece()));
|
| - CHECK(parsed.get());
|
| -
|
| - return *parsed;
|
| -}
|
| -
|
| -} // namespace test
|
| -} // namespace net
|
|
|