package types import ( "fmt" "github.com/google/certificate-transparency-go/tls" ) // StFormat defines a particular StItem type that is versioned type StFormat tls.Enum const ( StFormatReserved StFormat = 0 StFormatSignedTreeHeadV1 StFormat = 1 StFormatCosignedTreeHeadV1 StFormat = 2 StFormatConsistencyProofV1 StFormat = 3 StFormatInclusionProofV1 StFormat = 4 StFormatSignedChecksumV1 StFormat = 5 ) // StItem references a versioned item based on a given format specifier type StItem struct { Format StFormat `tls:"maxval:65535"` SignedTreeHeadV1 *SignedTreeHeadV1 `tls:"selector:Format,val:1"` CosignedTreeHeadV1 *CosignedTreeHeadV1 `tls:"selector:Format,val:2"` ConsistencyProofV1 *ConsistencyProofV1 `tls:"selector:Format,val:3"` InclusionProofV1 *InclusionProofV1 `tls:"selector:Format,val:4"` SignedChecksumV1 *SignedChecksumV1 `tls:"selector:Format,val:5"` } type StItemList struct { Items []StItem `tls:"minlen:0,maxlen:4294967295"` } type SignedTreeHeadV1 struct { TreeHead TreeHeadV1 Signature SignatureV1 } type CosignedTreeHeadV1 struct { SignedTreeHead SignedTreeHeadV1 Cosignatures []SignatureV1 `tls:"minlen:0,maxlen:4294967295"` } type ConsistencyProofV1 struct { LogId Namespace TreeSize1 uint64 TreeSize2 uint64 ConsistencyPath []NodeHash `tls:"minlen:0,maxlen:65535"` } type InclusionProofV1 struct { LogId Namespace TreeSize uint64 LeafIndex uint64 InclusionPath []NodeHash `tls:"minlen:0,maxlen:65535"` } type SignedChecksumV1 struct { Data ChecksumV1 Signature SignatureV1 } type ChecksumV1 struct { Identifier []byte `tls:"minlen:1,maxlen:128"` Checksum []byte `tls:"minlen:1,maxlen:64"` } type TreeHeadV1 struct { Timestamp uint64 TreeSize uint64 RootHash NodeHash Extension []byte `tls:"minlen:0,maxlen:65535"` } type NodeHash struct { Data []byte `tls:"minlen:32,maxlen:255"` } type SignatureV1 struct { Namespace Namespace Signature []byte `tls:"minlen:1,maxlen:65535"` } func (f StFormat) String() string { switch f { case StFormatReserved: return "reserved" case StFormatSignedTreeHeadV1: return "signed_tree_head_v1" case StFormatCosignedTreeHeadV1: return "cosigned_tree_head_v1" case StFormatConsistencyProofV1: return "consistency_proof_v1" case StFormatInclusionProofV1: return "inclusion_proof_v1" case StFormatSignedChecksumV1: return "signed_checksum_v1" default: return fmt.Sprintf("unknown StFormat: %d", f) } } func (i StItem) String() string { switch i.Format { case StFormatReserved: return fmt.Sprintf("Format(%s)", i.Format) case StFormatSignedTreeHeadV1: return fmt.Sprintf("Format(%s): %+v", i.Format, i.SignedTreeHeadV1) case StFormatCosignedTreeHeadV1: return fmt.Sprintf("Format(%s): %+v", i.Format, i.CosignedTreeHeadV1) case StFormatConsistencyProofV1: return fmt.Sprintf("Format(%s): %+v", i.Format, i.ConsistencyProofV1) case StFormatInclusionProofV1: return fmt.Sprintf("Format(%s): %+v", i.Format, i.InclusionProofV1) case StFormatSignedChecksumV1: return fmt.Sprintf("Format(%s): %+v", i.Format, i.SignedChecksumV1) default: return fmt.Sprintf("unknown StItem: %v", i.Format) } } func NewSignedTreeHeadV1(th *TreeHeadV1, sig *SignatureV1) *StItem { return &StItem{ Format: StFormatSignedTreeHeadV1, SignedTreeHeadV1: &SignedTreeHeadV1{ TreeHead: *th, Signature: *sig, }, } } func NewCosignedTreeHeadV1(sth *SignedTreeHeadV1, cosig []SignatureV1) *StItem { if cosig == nil { cosig = make([]SignatureV1, 0) } return &StItem{ Format: StFormatCosignedTreeHeadV1, CosignedTreeHeadV1: &CosignedTreeHeadV1{ SignedTreeHead: *sth, Cosignatures: cosig, }, } } func NewConsistencyProofV1(id *Namespace, size1, size2 uint64, path []NodeHash) *StItem { return &StItem{ Format: StFormatConsistencyProofV1, ConsistencyProofV1: &ConsistencyProofV1{ LogId: *id, TreeSize1: size1, TreeSize2: size2, ConsistencyPath: path, }, } } func NewInclusionProofV1(id *Namespace, size, index uint64, path []NodeHash) *StItem { return &StItem{ Format: StFormatInclusionProofV1, InclusionProofV1: &InclusionProofV1{ LogId: *id, TreeSize: size, LeafIndex: index, InclusionPath: path, }, } } func NewSignedChecksumV1(data *ChecksumV1, sig *SignatureV1) *StItem { return &StItem{ Format: StFormatSignedChecksumV1, SignedChecksumV1: &SignedChecksumV1{ Data: *data, Signature: *sig, }, } } func NewTreeHeadV1(timestamp, size uint64, hash, extension []byte) *TreeHeadV1 { if extension == nil { extension = make([]byte, 0) } return &TreeHeadV1{ Timestamp: timestamp, TreeSize: size, RootHash: NodeHash{ Data: hash, }, Extension: extension, } }