syntax = "proto2"; package ct; //////////////////////////////////////////////////////////////////////////////// // These protocol buffers should be kept aligned with the I-D. // //////////////////////////////////////////////////////////////////////////////// // RFC 5246 message DigitallySigned { enum HashAlgorithm { NONE = 0; MD5 = 1; SHA1 = 2; SHA224 = 3; SHA256 = 4; SHA384 = 5; SHA512 = 6; } enum SignatureAlgorithm { ANONYMOUS = 0; RSA = 1; DSA = 2; ECDSA = 3; } // 1 byte optional HashAlgorithm hash_algorithm = 1 [ default = NONE ]; // 1 byte optional SignatureAlgorithm sig_algorithm = 2 [ default = ANONYMOUS ]; // 0..2^16-1 bytes optional bytes signature = 3; } enum LogEntryType { X509_ENTRY = 0; PRECERT_ENTRY = 1; PRECERT_ENTRY_V2 = 2; // Not part of the I-D, and outside the valid range. X_JSON_ENTRY = 32768; // Experimental, don't rely on this! UNKNOWN_ENTRY_TYPE = 65536; } message X509ChainEntry { // For V1 this entry just includes the certificate in the leaf_certificate // field // <1..2^24-1> optional bytes leaf_certificate = 1; // For V2 it includes the cert and key hash using CertInfo. The // leaf_certificate field is not used optional CertInfo cert_info = 3; // <0..2^24-1> // A chain from the leaf to a trusted root // (excluding leaf and possibly root). repeated bytes certificate_chain = 2; } // opaque TBSCertificate<1..2^16-1>; // struct { // opaque issuer_key_hash[32]; // TBSCertificate tbs_certificate; // } PreCert; // Retained for V1 API compatibility. May be removed in a future release. message PreCert { optional bytes issuer_key_hash = 1; optional bytes tbs_certificate = 2; } // In V2 this is used for both certificates and precertificates in SCTs. It // replaces PreCert and has the same structure. The older message remains for // compatibility with existing code that depends on this proto. message CertInfo { optional bytes issuer_key_hash = 1; optional bytes tbs_certificate = 2; } message PrecertChainEntry { // <1..2^24-1> optional bytes pre_certificate = 1; // <0..2^24-1> // The chain certifying the precertificate, as submitted by the CA. repeated bytes precertificate_chain = 2; // PreCert input to the SCT. Can be computed from the above. // Store it alongside the entry data so that the signers don't have to // parse certificates to recompute it. optional PreCert pre_cert = 3; // As above for V2 messages. Only one of these fields will be set in a // valid message optional CertInfo cert_info = 4; } message XJSONEntry { optional string json = 1; } // TODO(alcutter): Consider using extensions here instead. message LogEntry { optional LogEntryType type = 1 [ default = UNKNOWN_ENTRY_TYPE ]; optional X509ChainEntry x509_entry = 2; optional PrecertChainEntry precert_entry = 3; optional XJSONEntry x_json_entry = 4; } enum SignatureType { CERTIFICATE_TIMESTAMP = 0; // TODO(ekasper): called tree_hash in I-D. TREE_HEAD = 1; } enum Version { V1 = 0; V2 = 1; // Not part of the I-D, and outside the valid range. UNKNOWN_VERSION = 256; } message LogID { // 32 bytes optional bytes key_id = 1; } message SctExtension { // Valid range is 0-65534 optional uint32 sct_extension_type = 1; // Data is opaque and type specific. <0..2^16-1> bytes optional bytes sct_extension_data = 2; } // TODO(ekasper): implement support for id. message SignedCertificateTimestamp { optional Version version = 1 [ default = UNKNOWN_VERSION ]; optional LogID id = 2; // UTC time in milliseconds, since January 1, 1970, 00:00. optional uint64 timestamp = 3; optional DigitallySigned signature = 4; // V1 extensions optional bytes extensions = 5; // V2 extensions <0..2^16-1>. Must be ordered by type (lowest first) repeated SctExtension sct_extension = 6; } message SignedCertificateTimestampList { // One or more SCTs, <1..2^16-1> bytes each repeated bytes sct_list = 1; } enum MerkleLeafType { TIMESTAMPED_ENTRY = 0; UNKNOWN_LEAF_TYPE = 256; } message SignedEntry { // For V1 signed entries either the x509 or precert field will be set optional bytes x509 = 1; optional PreCert precert = 2; optional bytes json = 3; // For V2 all entries use the CertInfo field and the above fields are // not set optional CertInfo cert_info = 4; } message TimestampedEntry { optional uint64 timestamp = 1; optional LogEntryType entry_type = 2; optional SignedEntry signed_entry = 3; // V1 extensions optional bytes extensions = 4; // V2 extensions <0..2^16-1>. Must be ordered by type (lowest first) repeated SctExtension sct_extension = 5; } // Stuff that's hashed into a Merkle leaf. message MerkleTreeLeaf { // The version of the corresponding SCT. optional Version version = 1 [ default = UNKNOWN_VERSION ]; optional MerkleLeafType type = 2 [ default = UNKNOWN_LEAF_TYPE ]; optional TimestampedEntry timestamped_entry = 3; } // TODO(benl): No longer needed? // // Used by cpp/client/ct: it assembles the one from the I-D JSON // protocol. // // Used by cpp/server/blob-server: it uses one to call a variant of // LogLookup::AuditProof. message MerkleAuditProof { optional Version version = 1 [ default = UNKNOWN_VERSION ]; optional LogID id = 2; optional int64 tree_size = 3; optional uint64 timestamp = 4; optional int64 leaf_index = 5; repeated bytes path_node = 6; optional DigitallySigned tree_head_signature = 7; } message ShortMerkleAuditProof { required int64 leaf_index = 1; repeated bytes path_node = 2; } //////////////////////////////////////////////////////////////////////////////// // Finally, stuff that's not in the I-D but that we use internally // // for logging entries and tree head state. // //////////////////////////////////////////////////////////////////////////////// // TODO(alcutter): Come up with a better name :/ message LoggedEntryPB { optional int64 sequence_number = 1; optional bytes merkle_leaf_hash = 2; message Contents { optional SignedCertificateTimestamp sct = 1; optional LogEntry entry = 2; } required Contents contents = 3; } message SthExtension { // Valid range is 0-65534 optional uint32 sth_extension_type = 1; // Data is opaque and type specific <0..2^16-1> bytes optional bytes sth_extension_data = 2; } message SignedTreeHead { // The version of the tree head signature. // (Note that each leaf has its own version, so a V2 tree // can contain V1 leaves, too. optional Version version = 1 [ default = UNKNOWN_VERSION ]; optional LogID id = 2; optional uint64 timestamp = 3; optional int64 tree_size = 4; optional bytes sha256_root_hash = 5; optional DigitallySigned signature = 6; // Only supported in V2. <0..2^16-1> repeated SthExtension sth_extension = 7; } // Stuff the SSL client spits out from a connection. message SSLClientCTData { optional LogEntry reconstructed_entry = 1; optional bytes certificate_sha256_hash = 2; message SCTInfo { // There is an entry + sct -> leaf hash mapping. optional SignedCertificateTimestamp sct = 1; optional bytes merkle_leaf_hash = 2; } repeated SCTInfo attached_sct_info = 3; } message ClusterNodeState { optional string node_id = 1; optional int64 contiguous_tree_size = 2 [deprecated = true]; optional SignedTreeHead newest_sth = 3; optional SignedTreeHead current_serving_sth = 4; // The following host_name/log_port pair are used to allow a log node to // contact other nodes in the cluster, primarily for the purposes of // replication. // hostname/ip which can be used to contact [just] this log node optional string hostname = 5; // port on which this log node is listening. optional int32 log_port = 6; } message ClusterControl { optional bool accept_new_entries = 1 [ default = true ]; } message ClusterConfig { ///////////////////////////////// // This section of the config affects the selection of the cluster's current // serving STH. // The cluster will always attempt to determine the newest (and // largest) possible STH which meets the constraints defined below from the // set of STHs available at the individual cluster nodes. // (Note that nodes with newer/larger STHs can, of course, serve // earlier/smaller STHs.) // The minimum number of nodes which must be able to serve a given STH. // This setting allows you to configure the level of cluster resiliency // against data (in the form of node/node database) loss. // i.e.: Once an STH has been created, it must have been replicated to // at least this many nodes before being considered as a candidate for // the overall cluster serving STH. optional int32 minimum_serving_nodes = 1; // The minimum fraction of nodes which must be able to serve a given STH. // This setting allows you to configure the serving capacity redundancy of // your cluster. // e.g. you determine you need 3 nodes to serve your expected peak traffic // levels, but want to be over-provisioned by 25% to ensure the cluster will // continue to be able to handle the traffic in the case of a single node // failure, you might set this to 0.75 to ensure that any cluster-wide // serving STH candidate must be servable from at least 3 of your 4 nodes. optional double minimum_serving_fraction = 2; ///////////////////////////////// // When the number of entries in the EtcedConsistentStore exceeds this value, // the log server will reject all calls to add-[pre-]chain to protect itself // and etcd. optional double etcd_reject_add_pending_threshold = 3 [default = 30000]; } message SequenceMapping { message Mapping { optional bytes entry_hash = 1; optional int64 sequence_number = 2; } repeated Mapping mapping = 1; }