12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_utils.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cstring> 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/base64.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sys_byteorder.h" 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/http/transport_security_state.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/ssl/ssl_info.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string HexDumpWithMarks(const unsigned char* data, int length, 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool* marks, int mark_length) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char kHexChars[] = "0123456789abcdef"; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const int kColumns = 4; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kSizeLimit = 1024; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (length > kSizeLimit || mark_length > kSizeLimit) { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) length = std::min(length, kSizeLimit); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mark_length = std::min(mark_length, kSizeLimit); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string hex; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (const unsigned char* row = data; length > 0; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) row += kColumns, length -= kColumns) { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (const unsigned char *p = row; p < row + 4; ++p) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (p < row + length) { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool mark = 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (marks && (p - data) < mark_length && marks[p - data]); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex += mark ? '*' : ' '; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex += kHexChars[(*p & 0xf0) >> 4]; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex += kHexChars[*p & 0x0f]; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex += mark ? '*' : ' '; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex += " "; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex = hex + " "; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (const unsigned char *p = row; p < row + 4 && p < row + length; ++p) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.'; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hex = hex + '\n'; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return hex; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CompareCharArraysWithHexError( 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& description, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char* actual, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int actual_len, 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char* expected, 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int expected_len) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int min_len = std::min(actual_len, expected_len); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int max_len = std::max(actual_len, expected_len); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<bool[]> marks(new bool[max_len]); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool identical = (actual_len == expected_len); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < min_len; ++i) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (actual[i] != expected[i]) { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) marks[i] = true; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) identical = false; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) marks[i] = false; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = min_len; i < max_len; ++i) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) marks[i] = true; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (identical) return; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ADD_FAILURE() 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Description:\n" 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << description 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "\n\nExpected:\n" 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << HexDumpWithMarks(expected, expected_len, marks.get(), max_len) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "\nActual:\n" 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid SetFrameFlags(SpdyFrame* frame, 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu uint8 flags, 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyMajorVersion spdy_version) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (spdy_version) { 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY2: 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY3: 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY4: 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY5: 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) frame->data()[4] = flags; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(FATAL) << "Unsupported SPDY version."; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid SetFrameLength(SpdyFrame* frame, 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t length, 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyMajorVersion spdy_version) { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (spdy_version) { 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY2: 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY3: 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(0u, length & ~kLengthMask); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 wire_length = base::HostToNet32(length); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The length field in SPDY 2 and 3 is a 24-bit (3B) integer starting at 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // offset 5. 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memcpy(frame->data() + 5, reinterpret_cast<char*>(&wire_length) + 1, 3); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY4: 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case SPDY5: 1224ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch CHECK_GT(1u<<14, length); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int32 wire_length = base::HostToNet32(length); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memcpy(frame->data(), 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) reinterpret_cast<char*>(&wire_length) + 1, 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(FATAL) << "Unsupported SPDY version."; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string a2b_hex(const char* hex_data) { 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<uint8> output; 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string result; 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (base::HexStringToBytes(hex_data, &output)) 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) result.assign(reinterpret_cast<const char*>(&output[0]), output.size()); 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return result; 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)HashValue GetTestHashValue(uint8_t label) { 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) HashValue hash_value(HASH_VALUE_SHA256); 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) memset(hash_value.data(), label, hash_value.size()); 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return hash_value; 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)std::string GetTestPin(uint8_t label) { 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) HashValue hash_value = GetTestHashValue(label); 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string base64; 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Base64Encode(base::StringPiece( 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) reinterpret_cast<char*>(hash_value.data()), hash_value.size()), &base64); 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return std::string("pin-sha256=\"") + base64 + "\""; 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void AddPin(TransportSecurityState* state, 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& host, 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8_t primary_label, 16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8_t backup_label) { 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string primary_pin = GetTestPin(primary_label); 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string backup_pin = GetTestPin(backup_label); 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string header = "max-age = 10000; " + primary_pin + "; " + backup_pin; 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Construct a fake SSLInfo that will pass AddHPKPHeader's checks. 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SSLInfo ssl_info; 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.is_issued_by_known_root = true; 16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssl_info.public_key_hashes.push_back(GetTestHashValue(primary_label)); 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(state->AddHPKPHeader(host, header, ssl_info)); 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace test 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace net 176