10 "github.com/google/certificate-transparency/go/x509"
14 issuerKeyHashLength = 32
17 ///////////////////////////////////////////////////////////////////////////////
18 // The following structures represent those outlined in the RFC6962 document:
19 ///////////////////////////////////////////////////////////////////////////////
21 // LogEntryType represents the LogEntryType enum from section 3.1 of the RFC:
22 // enum { x509_entry(0), precert_entry(1), (65535) } LogEntryType;
23 type LogEntryType uint16
25 func (e LogEntryType) String() string {
27 case X509LogEntryType:
28 return "X509LogEntryType"
29 case PrecertLogEntryType:
30 return "PrecertLogEntryType"
31 case XJSONLogEntryType:
32 return "XJSONLogEntryType"
34 panic(fmt.Sprintf("No string defined for LogEntryType constant value %d", e))
37 // LogEntryType constants, see section 3.1 of RFC6962.
39 X509LogEntryType LogEntryType = 0
40 PrecertLogEntryType LogEntryType = 1
41 XJSONLogEntryType LogEntryType = 0x8000 // Experimental. Don't rely on this!
44 // MerkleLeafType represents the MerkleLeafType enum from section 3.4 of the
45 // RFC: enum { timestamped_entry(0), (255) } MerkleLeafType;
46 type MerkleLeafType uint8
48 func (m MerkleLeafType) String() string {
50 case TimestampedEntryLeafType:
51 return "TimestampedEntryLeafType"
53 return fmt.Sprintf("UnknownLeafType(%d)", m)
57 // MerkleLeafType constants, see section 3.4 of the RFC.
59 TimestampedEntryLeafType MerkleLeafType = 0 // Entry type for an SCT
62 // Version represents the Version enum from section 3.2 of the RFC:
63 // enum { v1(0), (255) } Version;
66 func (v Version) String() string {
71 return fmt.Sprintf("UnknownVersion(%d)", v)
75 // CT Version constants, see section 3.2 of the RFC.
80 // SignatureType differentiates STH signatures from SCT signatures, see RFC
82 type SignatureType uint8
84 func (st SignatureType) String() string {
86 case CertificateTimestampSignatureType:
87 return "CertificateTimestamp"
88 case TreeHashSignatureType:
91 return fmt.Sprintf("UnknownSignatureType(%d)", st)
95 // SignatureType constants, see RFC section 3.2
97 CertificateTimestampSignatureType SignatureType = 0
98 TreeHashSignatureType SignatureType = 1
101 // ASN1Cert type for holding the raw DER bytes of an ASN.1 Certificate
105 // PreCert represents a Precertificate (section 3.2)
106 type PreCert struct {
107 IssuerKeyHash [issuerKeyHashLength]byte
108 TBSCertificate []byte
111 // CTExtensions is a representation of the raw bytes of any CtExtension
112 // structure (see section 3.2)
113 type CTExtensions []byte
115 // MerkleTreeNode represents an internal node in the CT tree
116 type MerkleTreeNode []byte
118 // ConsistencyProof represents a CT consistency proof (see sections 2.1.2 and
120 type ConsistencyProof []MerkleTreeNode
122 // AuditPath represents a CT inclusion proof (see sections 2.1.1 and 4.5)
123 type AuditPath []MerkleTreeNode
125 // LeafInput represents a serialized MerkleTreeLeaf structure
126 type LeafInput []byte
128 // HashAlgorithm from the DigitallySigned struct
129 type HashAlgorithm byte
131 // HashAlgorithm constants
133 None HashAlgorithm = 0
134 MD5 HashAlgorithm = 1
135 SHA1 HashAlgorithm = 2
136 SHA224 HashAlgorithm = 3
137 SHA256 HashAlgorithm = 4
138 SHA384 HashAlgorithm = 5
139 SHA512 HashAlgorithm = 6
142 func (h HashAlgorithm) String() string {
159 return fmt.Sprintf("UNKNOWN(%d)", h)
163 // SignatureAlgorithm from the the DigitallySigned struct
164 type SignatureAlgorithm byte
166 // SignatureAlgorithm constants
168 Anonymous SignatureAlgorithm = 0
169 RSA SignatureAlgorithm = 1
170 DSA SignatureAlgorithm = 2
171 ECDSA SignatureAlgorithm = 3
174 func (s SignatureAlgorithm) String() string {
185 return fmt.Sprintf("UNKNOWN(%d)", s)
189 // DigitallySigned represents an RFC5246 DigitallySigned structure
190 type DigitallySigned struct {
191 HashAlgorithm HashAlgorithm
192 SignatureAlgorithm SignatureAlgorithm
196 // FromBase64String populates the DigitallySigned structure from the base64 data passed in.
197 // Returns an error if the base64 data is invalid.
198 func (d *DigitallySigned) FromBase64String(b64 string) error {
199 raw, err := base64.StdEncoding.DecodeString(b64)
201 return fmt.Errorf("failed to unbase64 DigitallySigned: %v", err)
203 ds, err := UnmarshalDigitallySigned(bytes.NewReader(raw))
205 return fmt.Errorf("failed to unmarshal DigitallySigned: %v", err)
211 // Base64String returns the base64 representation of the DigitallySigned struct.
212 func (d DigitallySigned) Base64String() (string, error) {
213 b, err := MarshalDigitallySigned(d)
217 return base64.StdEncoding.EncodeToString(b), nil
220 // MarshalJSON implements the json.Marshaller interface.
221 func (d DigitallySigned) MarshalJSON() ([]byte, error) {
222 b64, err := d.Base64String()
226 return []byte(`"` + b64 + `"`), nil
229 // UnmarshalJSON implements the json.Unmarshaler interface.
230 func (d *DigitallySigned) UnmarshalJSON(b []byte) error {
232 if err := json.Unmarshal(b, &content); err != nil {
233 return fmt.Errorf("failed to unmarshal DigitallySigned: %v", err)
235 return d.FromBase64String(content)
238 // LogEntry represents the contents of an entry in a CT log, see section 3.1.
239 type LogEntry struct {
242 X509Cert *x509.Certificate
243 Precert *Precertificate
248 // SHA256Hash represents the output from the SHA256 hash function.
249 type SHA256Hash [sha256.Size]byte
251 // FromBase64String populates the SHA256 struct with the contents of the base64 data passed in.
252 func (s *SHA256Hash) FromBase64String(b64 string) error {
253 bs, err := base64.StdEncoding.DecodeString(b64)
255 return fmt.Errorf("failed to unbase64 LogID: %v", err)
257 if len(bs) != sha256.Size {
258 return fmt.Errorf("invalid SHA256 length, expected 32 but got %d", len(bs))
264 // Base64String returns the base64 representation of this SHA256Hash.
265 func (s SHA256Hash) Base64String() string {
266 return base64.StdEncoding.EncodeToString(s[:])
269 // MarshalJSON implements the json.Marshaller interface for SHA256Hash.
270 func (s SHA256Hash) MarshalJSON() ([]byte, error) {
271 return []byte(`"` + s.Base64String() + `"`), nil
274 // UnmarshalJSON implements the json.Unmarshaller interface.
275 func (s *SHA256Hash) UnmarshalJSON(b []byte) error {
277 if err := json.Unmarshal(b, &content); err != nil {
278 return fmt.Errorf("failed to unmarshal SHA256Hash: %v", err)
280 return s.FromBase64String(content)
283 // SignedTreeHead represents the structure returned by the get-sth CT method
284 // after base64 decoding. See sections 3.5 and 4.3 in the RFC)
285 type SignedTreeHead struct {
286 Version Version `json:"sth_version"` // The version of the protocol to which the STH conforms
287 TreeSize uint64 `json:"tree_size"` // The number of entries in the new tree
288 Timestamp uint64 `json:"timestamp"` // The time at which the STH was created
289 SHA256RootHash SHA256Hash `json:"sha256_root_hash"` // The root hash of the log's Merkle tree
290 TreeHeadSignature DigitallySigned `json:"tree_head_signature"` // The Log's signature for this STH (see RFC section 3.5)
291 LogID SHA256Hash `json:"log_id"` // The SHA256 hash of the log's public key
294 // SignedCertificateTimestamp represents the structure returned by the
295 // add-chain and add-pre-chain methods after base64 decoding. (see RFC sections
297 type SignedCertificateTimestamp struct {
298 SCTVersion Version // The version of the protocol to which the SCT conforms
299 LogID SHA256Hash // the SHA-256 hash of the log's public key, calculated over
300 // the DER encoding of the key represented as SubjectPublicKeyInfo.
301 Timestamp uint64 // Timestamp (in ms since unix epoc) at which the SCT was issued
302 Extensions CTExtensions // For future extensions to the protocol
303 Signature DigitallySigned // The Log's signature for this SCT
306 func (s SignedCertificateTimestamp) String() string {
307 return fmt.Sprintf("{Version:%d LogId:%s Timestamp:%d Extensions:'%s' Signature:%v}", s.SCTVersion,
308 base64.StdEncoding.EncodeToString(s.LogID[:]),
314 // TimestampedEntry is part of the MerkleTreeLeaf structure.
315 // See RFC section 3.4
316 type TimestampedEntry struct {
318 EntryType LogEntryType
322 Extensions CTExtensions
325 // MerkleTreeLeaf represents the deserialized sructure of the hash input for the
326 // leaves of a log's Merkle tree. See RFC section 3.4
327 type MerkleTreeLeaf struct {
328 Version Version // the version of the protocol to which the MerkleTreeLeaf corresponds
329 LeafType MerkleLeafType // The type of the leaf input, currently only TimestampedEntry can exist
330 TimestampedEntry TimestampedEntry // The entry data itself
333 // Precertificate represents the parsed CT Precertificate structure.
334 type Precertificate struct {
335 // Raw DER bytes of the precert
337 // SHA256 hash of the issuing key
338 IssuerKeyHash [issuerKeyHashLength]byte
339 // Parsed TBSCertificate structure (held in an x509.Certificate for ease of
341 TBSCertificate x509.Certificate
344 // X509Certificate returns the X.509 Certificate contained within the
346 // Returns a pointer to an x509.Certificate or a non-nil error.
347 func (m *MerkleTreeLeaf) X509Certificate() (*x509.Certificate, error) {
348 return x509.ParseCertificate(m.TimestampedEntry.X509Entry)
353 // Preallocate errors for performance
355 ErrInvalidVersion error = sctError(1)
356 ErrNotEnoughBuffer error = sctError(2)
359 func (e sctError) Error() string {
361 case ErrInvalidVersion:
362 return "invalid SCT version detected"
363 case ErrNotEnoughBuffer:
364 return "provided buffer was too small"
366 return "unknown error"
370 // AddJSONRequest represents the JSON request body sent ot the add-json CT
372 type AddJSONRequest struct {
373 Data interface{} `json:"data"`