github.com/google/trillian-examples@v0.0.0-20240520080811-0d40d35cef0e/binary_transparency/firmware/internal/client/utils.go (about) 1 // Copyright 2020 Google LLC. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package client 16 17 import ( 18 "context" 19 "fmt" 20 "time" 21 22 "github.com/golang/glog" 23 "github.com/google/trillian-examples/binary_transparency/firmware/api" 24 "github.com/transparency-dev/merkle/proof" 25 "github.com/transparency-dev/merkle/rfc6962" 26 ) 27 28 // AwaitInclusion waits for the specified statement s to be included into the log and then 29 // returns the checkpoint under which it was found to be present, along with valid consistency and inclusion proofs. 30 func AwaitInclusion(ctx context.Context, c *ReadonlyClient, cp api.LogCheckpoint, s []byte) (api.LogCheckpoint, api.ConsistencyProof, api.InclusionProof, error) { 31 lh := rfc6962.DefaultHasher 32 for { 33 select { 34 case <-time.After(1 * time.Second): 35 // 36 case <-ctx.Done(): 37 return api.LogCheckpoint{}, api.ConsistencyProof{}, api.InclusionProof{}, ctx.Err() 38 } 39 40 newCP, err := c.GetCheckpoint() 41 if err != nil { 42 return api.LogCheckpoint{}, api.ConsistencyProof{}, api.InclusionProof{}, err 43 } 44 45 if newCP.Size <= cp.Size { 46 glog.V(1).Info("Waiting for tree to integrate new leaves") 47 continue 48 } 49 var consistency api.ConsistencyProof 50 if cp.Size > 0 { 51 cproof, err := c.GetConsistencyProof(api.GetConsistencyRequest{From: cp.Size, To: newCP.Size}) 52 if err != nil { 53 glog.Warningf("Received error while fetching consistency proof: %q", err) 54 continue 55 } 56 consistency = *cproof 57 if err := proof.VerifyConsistency(lh, cp.Size, newCP.Size, consistency.Proof, cp.Hash, newCP.Hash); err != nil { 58 // Whoa Nelly, this is bad - bail! 59 glog.Warning("Invalid consistency proof received!") 60 return *newCP, consistency, api.InclusionProof{}, fmt.Errorf("invalid inclusion proof received: %w", err) 61 } 62 glog.Infof("Consistency proof between %d and %d verified", cp.Size, newCP.Size) 63 } 64 cp = *newCP 65 66 ip, err := c.GetInclusion(s, cp) 67 if err != nil { 68 glog.Warningf("Received error while fetching inclusion proof: %q", err) 69 continue 70 } 71 if err := proof.VerifyInclusion(lh, ip.LeafIndex, cp.Size, lh.HashLeaf(s), ip.Proof, cp.Hash); err != nil { 72 // Whoa Nelly, this is bad - bail! 73 glog.Warning("Invalid inclusion proof received!") 74 return cp, consistency, ip, fmt.Errorf("invalid inclusion proof received: %w", err) 75 } 76 77 glog.Infof("Inclusion proof for leafhash 0x%x verified", lh) 78 return cp, consistency, ip, nil 79 } 80 // unreachable 81 }