File: serializer.h

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (237 lines) | stat: -rw-r--r-- 9,085 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#ifndef CERT_TRANS_PROTO_SERIALIZER_H_
#define CERT_TRANS_PROTO_SERIALIZER_H_

#include <glog/logging.h>
#include <google/protobuf/repeated_field.h>
#include <stdint.h>
#include <functional>
#include <string>

#include "base/macros.h"
#include "proto/ct.pb.h"
#include "proto/tls_encoding.h"

typedef google::protobuf::RepeatedPtrField<ct::SthExtension>
    repeated_sth_extension;
typedef google::protobuf::RepeatedPtrField<ct::SctExtension>
    repeated_sct_extension;

cert_trans::serialization::SerializeResult CheckExtensionsFormat(
    const std::string& extensions);
cert_trans::serialization::SerializeResult CheckKeyHashFormat(
    const std::string& key_hash);
cert_trans::serialization::SerializeResult CheckSctExtensionsFormat(
    const repeated_sct_extension& extension);

void WriteSctExtension(const repeated_sct_extension& extension,
                       std::string* output);

class TLSDeserializer {
 public:
  // We do not make a copy, so input must remain valid.
  // TODO(pphaneuf): And so we should take a string *, not a string &
  // (which could be to a temporary, and not valid once the
  // constructor returns).
  explicit TLSDeserializer(const std::string& input);

  bool ReachedEnd() const {
    return bytes_remaining_ == 0;
  }

  cert_trans::serialization::DeserializeResult ReadSCT(
      ct::SignedCertificateTimestamp* sct);

  cert_trans::serialization::DeserializeResult ReadList(
      size_t max_total_length, size_t max_elem_length, repeated_string* out);

  cert_trans::serialization::DeserializeResult ReadDigitallySigned(
      ct::DigitallySigned* sig);

  cert_trans::serialization::DeserializeResult ReadMerkleTreeLeaf(
      ct::MerkleTreeLeaf* leaf);
  bool ReadVarBytes(size_t max_length, std::string* result);

  template <class T>
  bool ReadUint(size_t bytes, T* result) {
    if (bytes_remaining_ < bytes)
      return false;
    T res = 0;
    for (size_t i = 0; i < bytes; ++i) {
      res = (res << 8) | static_cast<unsigned char>(*current_pos_);
      ++current_pos_;
    }

    bytes_remaining_ -= bytes;
    *result = res;
    return true;
  }

  cert_trans::serialization::DeserializeResult ReadExtensions(
      ct::TimestampedEntry* entry);
  bool ReadFixedBytes(size_t bytes, std::string* result);

 private:
  static const size_t kV2ExtensionCountLengthInBytes;
  static const size_t kV2ExtensionTypeLengthInBytes;

  cert_trans::serialization::DeserializeResult ReadSctExtension(
      repeated_sct_extension* extension);
  cert_trans::serialization::DeserializeResult ReadMerkleTreeLeafV1(
      ct::MerkleTreeLeaf* leaf);
  cert_trans::serialization::DeserializeResult ReadMerkleTreeLeafV2(
      ct::MerkleTreeLeaf* leaf);
  cert_trans::serialization::DeserializeResult ReadSCTV1(
      ct::SignedCertificateTimestamp* sct);
  cert_trans::serialization::DeserializeResult ReadSCTV2(
      ct::SignedCertificateTimestamp* sct);
  bool ReadLengthPrefix(size_t max_length, size_t* result);

  const char* current_pos_;
  size_t bytes_remaining_;

  DISALLOW_COPY_AND_ASSIGN(TLSDeserializer);
};

// A utility class for writing protocol buffer fields in canonical TLS style.
class Serializer {
 public:
  static const size_t kMaxV2ExtensionType;
  static const size_t kMaxV2ExtensionsCount;
  static const size_t kMaxExtensionsLength;
  static const size_t kMaxSerializedSCTLength;
  static const size_t kMaxSCTListLength;

  static const size_t kLogEntryTypeLengthInBytes;
  static const size_t kSignatureTypeLengthInBytes;
  static const size_t kVersionLengthInBytes;
  // Log Key ID
  static const size_t kKeyIDLengthInBytes;
  static const size_t kMerkleLeafTypeLengthInBytes;
  // Public key hash from cert
  static const size_t kKeyHashLengthInBytes;
  static const size_t kTimestampLengthInBytes;

  // API
  // TODO(alcutter): typedef these function<> bits
  static void ConfigureV1(
      const std::function<std::string(const ct::LogEntry&)>& leaf_data,
      const std::function<cert_trans::serialization::SerializeResult(
          const ct::SignedCertificateTimestamp& sct, const ct::LogEntry& entry,
          std::string* result)>& serialize_sct_sig_input,
      const std::function<cert_trans::serialization::SerializeResult(
          const ct::SignedCertificateTimestamp& sct, const ct::LogEntry& entry,
          std::string* result)>& serialize_sct_merkle_leaf);

  static void ConfigureV2(
      const std::function<std::string(const ct::LogEntry&)>& leaf_data,
      const std::function<cert_trans::serialization::SerializeResult(
          const ct::SignedCertificateTimestamp& sct, const ct::LogEntry& entry,
          std::string* result)>& serialize_sct_sig_input,
      const std::function<cert_trans::serialization::SerializeResult(
          const ct::SignedCertificateTimestamp& sct, const ct::LogEntry& entry,
          std::string* result)>& serialize_sct_merkle_leaf);

  static std::string LeafData(const ct::LogEntry& entry);

  static cert_trans::serialization::SerializeResult SerializeSTHSignatureInput(
      const ct::SignedTreeHead& sth, std::string* result);

  static cert_trans::serialization::SerializeResult SerializeSCTMerkleTreeLeaf(
      const ct::SignedCertificateTimestamp& sct, const ct::LogEntry& entry,
      std::string* result);

  static cert_trans::serialization::SerializeResult SerializeSCTSignatureInput(
      const ct::SignedCertificateTimestamp& sct, const ct::LogEntry& entry,
      std::string* result);

  static cert_trans::serialization::SerializeResult
  SerializeV1STHSignatureInput(uint64_t timestamp, int64_t tree_size,
                               const std::string& root_hash,
                               std::string* result);

  static cert_trans::serialization::SerializeResult
  SerializeV2STHSignatureInput(uint64_t timestamp, int64_t tree_size,
                               const std::string& root_hash,
                               const repeated_sth_extension& sth_extension,
                               const std::string& log_id, std::string* result);


  // Random utils
  static cert_trans::serialization::SerializeResult SerializeList(
      const repeated_string& in, size_t max_elem_length,
      size_t max_total_length, std::string* result);

  static cert_trans::serialization::SerializeResult SerializeSCT(
      const ct::SignedCertificateTimestamp& sct, std::string* result);

  static cert_trans::serialization::SerializeResult SerializeSCTList(
      const ct::SignedCertificateTimestampList& sct_list, std::string* result);

  static cert_trans::serialization::SerializeResult SerializeDigitallySigned(
      const ct::DigitallySigned& sig, std::string* result);

  // TODO(ekasper): tests for these!
  template <class T>
  static std::string SerializeUint(T in, size_t bytes = sizeof(T)) {
    std::string out;
    cert_trans::serialization::WriteUint(in, bytes, &out);
    return out;
  }

 private:
  // This class is mostly a namespace for static methods.
  // TODO(pphaneuf): Make this into normal functions in a namespace.
  Serializer() = delete;
};


class Deserializer {
 public:
  static void Configure(
      const std::function<cert_trans::serialization::DeserializeResult(
          TLSDeserializer* d, ct::MerkleTreeLeaf* leaf)>&
          read_merkle_tree_leaf_body);

  static cert_trans::serialization::DeserializeResult DeserializeSCT(
      const std::string& in, ct::SignedCertificateTimestamp* sct);

  static cert_trans::serialization::DeserializeResult DeserializeSCTList(
      const std::string& in, ct::SignedCertificateTimestampList* sct_list);

  static cert_trans::serialization::DeserializeResult
  DeserializeDigitallySigned(const std::string& in, ct::DigitallySigned* sig);

  // FIXME(ekasper): for simplicity these reject if the list has empty
  // elements (all our use cases are like this) but they should take in
  // an arbitrary min bound instead.
  static cert_trans::serialization::DeserializeResult DeserializeList(
      const std::string& in, size_t max_total_length, size_t max_elem_length,
      repeated_string* out);

  static cert_trans::serialization::DeserializeResult
  DeserializeMerkleTreeLeaf(const std::string& in, ct::MerkleTreeLeaf* leaf);

  // TODO(pphaneuf): Maybe the users of this should just use
  // TLSDeserializer directly?
  template <class T>
  static cert_trans::serialization::DeserializeResult DeserializeUint(
      const std::string& in, size_t bytes, T* result) {
    TLSDeserializer deserializer(in);
    bool res = deserializer.ReadUint(bytes, result);
    if (!res)
      return cert_trans::serialization::DeserializeResult::INPUT_TOO_SHORT;
    if (!deserializer.ReachedEnd())
      return cert_trans::serialization::DeserializeResult::INPUT_TOO_LONG;
    return cert_trans::serialization::DeserializeResult::OK;
  }

 private:
  // This class is mostly a namespace for static methods.
  // TODO(pphaneuf): Make this into normal functions in a namespace.
  Deserializer() = delete;

  // This should never do anything, but just in case...
  DISALLOW_COPY_AND_ASSIGN(Deserializer);
};

#endif  // CERT_TRANS_PROTO_SERIALIZER_H_