15
15
package client
16
16
17
17
import (
18
+ "bytes"
18
19
"crypto/tls"
20
+ "encoding/base64"
21
+ "encoding/hex"
22
+ "fmt"
19
23
"net/http"
20
24
"net/url"
21
25
@@ -24,8 +28,13 @@ import (
24
28
"github.com/go-openapi/strfmt"
25
29
"github.com/hashicorp/go-cleanhttp"
26
30
retryablehttp "github.com/hashicorp/go-retryablehttp"
31
+ rekor_pb_common "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
32
+ rekor_pb "github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1"
27
33
"github.com/sigstore/rekor/pkg/generated/client"
34
+ "github.com/sigstore/rekor/pkg/generated/models"
35
+ "github.com/sigstore/rekor/pkg/types"
28
36
"github.com/sigstore/rekor/pkg/util"
37
+ "google.golang.org/protobuf/encoding/protojson"
29
38
)
30
39
31
40
func GetRekorClient (rekorServerURL string , opts ... Option ) (* client.Rekor , error ) {
@@ -64,3 +73,70 @@ func GetRekorClient(rekorServerURL string, opts ...Option) (*client.Rekor, error
64
73
registry .Add ("signedCheckpoint" , & util.SignedNote {}, util .SignedCheckpointValidator )
65
74
return client .New (rt , registry ), nil
66
75
}
76
+
77
+ // GenerateTransparencyLogEntry returns a sigstore/protobuf-specs compliant message containing a
78
+ // TransparencyLogEntry as defined at https://github.com/sigstore/protobuf-specs/blob/main/protos/sigstore_rekor.proto
79
+ func GenerateTransparencyLogEntry (anon models.LogEntryAnon ) (* rekor_pb.TransparencyLogEntry , error ) {
80
+ logIDHash , err := hex .DecodeString (* anon .LogID )
81
+ if err != nil {
82
+ return nil , fmt .Errorf ("decoding logID string: %w" , err )
83
+ }
84
+
85
+ rootHash , err := hex .DecodeString (* anon .Verification .InclusionProof .RootHash )
86
+ if err != nil {
87
+ return nil , fmt .Errorf ("decoding inclusion proof root hash: %w" , err )
88
+ }
89
+
90
+ inclusionProofHashes := make ([][]byte , len (anon .Verification .InclusionProof .Hashes ))
91
+ for i , hash := range anon .Verification .InclusionProof .Hashes {
92
+ hashBytes , err := hex .DecodeString (hash )
93
+ if err != nil {
94
+ return nil , fmt .Errorf ("decoding inclusion proof hash: %w" , err )
95
+ }
96
+ inclusionProofHashes [i ] = hashBytes
97
+ }
98
+
99
+ b , err := base64 .StdEncoding .DecodeString (anon .Body .(string ))
100
+ if err != nil {
101
+ return nil , fmt .Errorf ("base64 decoding body: %w" , err )
102
+ }
103
+
104
+ pe , err := models .UnmarshalProposedEntry (bytes .NewReader (b ), runtime .JSONConsumer ())
105
+ if err != nil {
106
+ return nil , err
107
+ }
108
+ eimpl , err := types .UnmarshalEntry (pe )
109
+ if err != nil {
110
+ return nil , err
111
+ }
112
+
113
+ return & rekor_pb.TransparencyLogEntry {
114
+ LogIndex : * anon .LogIndex ,
115
+ LogId : & rekor_pb_common.LogId {
116
+ KeyId : logIDHash ,
117
+ },
118
+ KindVersion : & rekor_pb.KindVersion {
119
+ Kind : pe .Kind (),
120
+ Version : eimpl .APIVersion (),
121
+ },
122
+ IntegratedTime : * anon .IntegratedTime ,
123
+ InclusionPromise : & rekor_pb.InclusionPromise {
124
+ SignedEntryTimestamp : anon .Verification .SignedEntryTimestamp ,
125
+ },
126
+ InclusionProof : & rekor_pb.InclusionProof {
127
+ LogIndex : * anon .LogIndex ,
128
+ RootHash : rootHash ,
129
+ TreeSize : * anon .Verification .InclusionProof .TreeSize ,
130
+ Hashes : inclusionProofHashes ,
131
+ Checkpoint : & rekor_pb.Checkpoint {
132
+ Envelope : * anon .Verification .InclusionProof .Checkpoint ,
133
+ },
134
+ },
135
+ CanonicalizedBody : b , // we don't call eimpl.Canonicalize in the case that the logic is different in this caller vs when it was persisted in the log
136
+ }, nil
137
+ }
138
+
139
+ // MarshalTLEToJSON marshals a TransparencyLogEntry message to JSON according to the protobuf JSON encoding rules
140
+ func MarshalTLEToJSON (tle * rekor_pb.TransparencyLogEntry ) ([]byte , error ) {
141
+ return protojson .Marshal (tle )
142
+ }
0 commit comments