1// Copyright (c) 2006-2008 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#ifndef CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_PARSER_H_
6#define CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_PARSER_H_
7#pragma once
8
9// Parse the data returned from the chunk response.
10//
11// Based on the SafeBrowsing v2.1 protocol:
12// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec
13//
14// Read the response from a SafeBrowsing request, and parse into useful pieces.
15// The protocol is generally line oriented, but can contain binary data in the
16// actual chunk responses. The consumer of the protocol data should instantiate
17// the parser and call the appropriate parsing function on the data.
18//
19// Examples of protocol responses:
20//
21// 1. List identification
22//    i:goog-phish-shavar\n
23//    <command>:<command_data>\n
24//
25// 2. Minimum time to wait (seconds) until the next download request can be made
26//    n:1200\n
27//    <command>:<time_in_seconds>\n
28//
29// 3. Redirect URL for retrieving a chunk
30//    u:cache.googlevideo.com/safebrowsing/rd/goog-phish-shavar_a_1\n
31//    <command>:<url>\n
32//
33// 4. Add and sub chunks
34//   a:1:4:523\n...    <-- Add chunk + binary data
35//   s:13:4:17\n...    <-- Sub chunk + binary data
36//   <chunk_type>:<chunk_number>:<prefix_len>:<chunk_bytes>\n<binary_data>
37//
38// 5. Add-del and sub-del requests
39//    ad:1-4000,5001\n    <-- Add-del
40//    sd:1,3,5,7,903\n    <-- Sub-del
41//    <command>:<chunk_range>\n
42
43
44#include <string>
45#include <vector>
46
47#include "base/basictypes.h"
48#include "chrome/browser/safe_browsing/chunk_range.h"
49#include "chrome/browser/safe_browsing/safe_browsing_util.h"
50
51
52class SafeBrowsingProtocolParser {
53 public:
54  SafeBrowsingProtocolParser();
55
56  // Parse the response of an update request. Results for chunk deletions (both
57  // add-del and sub-del are returned in 'chunk_deletes', and new chunk URLs to
58  // download are contained in 'chunk_urls'. The next time the client is allowed
59  // to request another update is returned in 'next_update_sec'. If the service
60  // wants us to retrieve new MAC keys, 're_key' will be set to true. If we are
61  // using MACs to verify responses, the 'key' must be set to the private key
62  // returned from the SafeBrowsing servers. 'reset' will be set to true if the
63  // SafeBrowsing service wants us to dump our database.
64  // Returns 'true'if it was able to decode the chunk properly, 'false' if not
65  // decoded properly and the results should be ignored.
66  bool ParseUpdate(const char* chunk_data,
67                   int chunk_len,
68                   const std::string& key,
69                   int* next_update_sec,
70                   bool* re_key,
71                   bool* reset,
72                   std::vector<SBChunkDelete>* chunk_deletes,
73                   std::vector<ChunkUrl>* chunk_urls);
74
75  // Parse the response from a chunk URL request and returns the hosts/prefixes
76  // for adds and subs in "chunks".  Returns 'true' on successful parsing,
77  // 'false' otherwise. Any result should be ignored when a parse has failed.
78  bool ParseChunk(const std::string& list_name,
79                  const char* chunk_data,
80                  int chunk_len,
81                  const std::string& key,
82                  const std::string& mac,
83                  bool* re_key,
84                  SBChunkList* chunks);
85
86  // Parse the result of a GetHash request, returning the list of full hashes.
87  // If we are checking for valid MACs, the caller should populate 'key'.
88  bool ParseGetHash(const char* chunk_data,
89                    int chunk_len,
90                    const std::string& key,
91                    bool* re_key,
92                    std::vector<SBFullHashResult>* full_hashes);
93
94  // Convert a list of partial hashes into a proper GetHash request.
95  void FormatGetHash(const std::vector<SBPrefix>& prefixes,
96                     std::string* request);
97
98  // Parse the keys used for subsequent communications with the SafeBrowsing
99  // servers. Returns true on successful parse, false on parse error.
100  bool ParseNewKey(const char* chunk_data,
101                   int chunk_length,
102                   std::string* client_key,
103                   std::string* wrapped_key);
104
105 private:
106  bool ParseAddChunk(const std::string& list_name,
107                     const char* data,
108                     int data_len,
109                     int hash_len,
110                     std::deque<SBChunkHost>* hosts);
111  bool ParseSubChunk(const std::string& list_name,
112                     const char* data,
113                     int data_len,
114                     int hash_len,
115                     std::deque<SBChunkHost>* hosts);
116
117  // Helper functions used by ParseAddChunk and ParseSubChunk.
118  static void ReadHostAndPrefixCount(const char** data,
119                                     int* remaining,
120                                     SBPrefix* host,
121                                     int* count);
122  static int ReadChunkId(const char** data, int* remaining);
123  static bool ReadPrefixes(
124      const char** data, int* remaining, SBEntry* entry, int count);
125
126  // The name of the current list
127  std::string list_name_;
128
129  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingProtocolParser);
130};
131
132
133#endif  // CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_PARSER_H_
134