...

Source file src/github.com/sigstore/rekor/pkg/tle/tle.go

Documentation: github.com/sigstore/rekor/pkg/tle

     1  // Copyright 2021 The Sigstore Authors.
     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 tle
    16  
    17  import (
    18  	"bytes"
    19  	"encoding/base64"
    20  	"encoding/hex"
    21  	"fmt"
    22  
    23  	"github.com/go-openapi/runtime"
    24  	rekor_pb_common "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
    25  	rekor_pb "github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1"
    26  	"github.com/sigstore/rekor/pkg/generated/models"
    27  	"github.com/sigstore/rekor/pkg/types"
    28  	"google.golang.org/protobuf/encoding/protojson"
    29  )
    30  
    31  // GenerateTransparencyLogEntry returns a sigstore/protobuf-specs compliant message containing a
    32  // TransparencyLogEntry as defined at https://github.com/sigstore/protobuf-specs/blob/main/protos/sigstore_rekor.proto
    33  func GenerateTransparencyLogEntry(anon models.LogEntryAnon) (*rekor_pb.TransparencyLogEntry, error) {
    34  	logIDHash, err := hex.DecodeString(*anon.LogID)
    35  	if err != nil {
    36  		return nil, fmt.Errorf("decoding logID string: %w", err)
    37  	}
    38  
    39  	rootHash, err := hex.DecodeString(*anon.Verification.InclusionProof.RootHash)
    40  	if err != nil {
    41  		return nil, fmt.Errorf("decoding inclusion proof root hash: %w", err)
    42  	}
    43  
    44  	inclusionProofHashes := make([][]byte, len(anon.Verification.InclusionProof.Hashes))
    45  	for i, hash := range anon.Verification.InclusionProof.Hashes {
    46  		hashBytes, err := hex.DecodeString(hash)
    47  		if err != nil {
    48  			return nil, fmt.Errorf("decoding inclusion proof hash: %w", err)
    49  		}
    50  		inclusionProofHashes[i] = hashBytes
    51  	}
    52  
    53  	// Different call paths may supply string or []byte. If string, it is base64 encoded.
    54  	var body []byte
    55  	switch v := anon.Body.(type) {
    56  	case string:
    57  		b, err := base64.StdEncoding.DecodeString(v)
    58  		if err != nil {
    59  			return nil, fmt.Errorf("base64 decoding body: %w", err)
    60  		}
    61  		body = b
    62  	case []byte:
    63  		body = v
    64  	default:
    65  		return nil, fmt.Errorf("body is not string or []byte: (%T)%v", v, v)
    66  	}
    67  
    68  	pe, err := models.UnmarshalProposedEntry(bytes.NewReader(body), runtime.JSONConsumer())
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	eimpl, err := types.UnmarshalEntry(pe)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	return &rekor_pb.TransparencyLogEntry{
    78  		LogIndex: *anon.LogIndex, // the global log index
    79  		LogId: &rekor_pb_common.LogId{
    80  			KeyId: logIDHash,
    81  		},
    82  		KindVersion: &rekor_pb.KindVersion{
    83  			Kind:    pe.Kind(),
    84  			Version: eimpl.APIVersion(),
    85  		},
    86  		IntegratedTime: *anon.IntegratedTime,
    87  		InclusionPromise: &rekor_pb.InclusionPromise{
    88  			SignedEntryTimestamp: anon.Verification.SignedEntryTimestamp,
    89  		},
    90  		InclusionProof: &rekor_pb.InclusionProof{
    91  			LogIndex: *anon.Verification.InclusionProof.LogIndex, // relative to the specific tree the entry is found in
    92  			RootHash: rootHash,
    93  			TreeSize: *anon.Verification.InclusionProof.TreeSize,
    94  			Hashes:   inclusionProofHashes,
    95  			Checkpoint: &rekor_pb.Checkpoint{
    96  				Envelope: *anon.Verification.InclusionProof.Checkpoint,
    97  			},
    98  		},
    99  		CanonicalizedBody: body, // 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
   100  	}, nil
   101  }
   102  
   103  // MarshalTLEToJSON marshals a TransparencyLogEntry message to JSON according to the protobuf JSON encoding rules
   104  func MarshalTLEToJSON(tle *rekor_pb.TransparencyLogEntry) ([]byte, error) {
   105  	return protojson.Marshal(tle)
   106  }
   107  

View as plain text