...

Source file src/github.com/google/certificate-transparency-go/client/ctclient/cmd/get_entries.go

Documentation: github.com/google/certificate-transparency-go/client/ctclient/cmd

     1  // Copyright 2022 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 cmd
    16  
    17  import (
    18  	"context"
    19  	"encoding/pem"
    20  	"fmt"
    21  	"os"
    22  
    23  	ct "github.com/google/certificate-transparency-go"
    24  	"github.com/google/certificate-transparency-go/x509"
    25  	"github.com/google/certificate-transparency-go/x509util"
    26  	"github.com/spf13/cobra"
    27  	"k8s.io/klog/v2"
    28  )
    29  
    30  var (
    31  	getFirst int64
    32  	getLast  int64
    33  	chainOut bool
    34  	textOut  bool
    35  )
    36  
    37  func init() {
    38  	cmd := cobra.Command{
    39  		Use:     fmt.Sprintf("get-entries %s --first=idx [--last=idx]", connectionFlags),
    40  		Aliases: []string{"getentries", "entries"},
    41  		Short:   "Fetch a range of entries in the log",
    42  		Args:    cobra.MaximumNArgs(0),
    43  		Run: func(cmd *cobra.Command, _ []string) {
    44  			runGetEntries(cmd.Context())
    45  		},
    46  	}
    47  	cmd.Flags().Int64Var(&getFirst, "first", -1, "First entry to get")
    48  	cmd.Flags().Int64Var(&getLast, "last", -1, "Last entry to get")
    49  	cmd.Flags().BoolVar(&chainOut, "chain", false, "Display entire certificate chain")
    50  	cmd.Flags().BoolVar(&textOut, "text", true, "Display certificates as text")
    51  	rootCmd.AddCommand(&cmd)
    52  }
    53  
    54  // runGetEntries runs the get-entries command.
    55  func runGetEntries(ctx context.Context) {
    56  	logClient := connect(ctx)
    57  	if getFirst == -1 {
    58  		klog.Exit("No -first option supplied")
    59  	}
    60  	if getLast == -1 {
    61  		getLast = getFirst
    62  	}
    63  	rsp, err := logClient.GetRawEntries(ctx, getFirst, getLast)
    64  	if err != nil {
    65  		exitWithDetails(err)
    66  	}
    67  
    68  	for i, rawEntry := range rsp.Entries {
    69  		index := getFirst + int64(i)
    70  		rle, err := ct.RawLogEntryFromLeaf(index, &rawEntry)
    71  		if err != nil {
    72  			fmt.Printf("Index=%d Failed to unmarshal leaf entry: %v", index, err)
    73  			continue
    74  		}
    75  		showRawLogEntry(rle)
    76  	}
    77  }
    78  
    79  func showRawLogEntry(rle *ct.RawLogEntry) {
    80  	ts := rle.Leaf.TimestampedEntry
    81  	when := ct.TimestampToTime(ts.Timestamp)
    82  	fmt.Printf("Index=%d Timestamp=%d (%v) ", rle.Index, ts.Timestamp, when)
    83  
    84  	switch ts.EntryType {
    85  	case ct.X509LogEntryType:
    86  		fmt.Printf("X.509 certificate:\n")
    87  		showRawCert(*ts.X509Entry)
    88  	case ct.PrecertLogEntryType:
    89  		fmt.Printf("pre-certificate from issuer with keyhash %x:\n", ts.PrecertEntry.IssuerKeyHash)
    90  		showRawCert(rle.Cert) // As-submitted: with signature and poison.
    91  	default:
    92  		fmt.Printf("Unhandled log entry type %d\n", ts.EntryType)
    93  	}
    94  	if chainOut {
    95  		for _, c := range rle.Chain {
    96  			showRawCert(c)
    97  		}
    98  	}
    99  }
   100  
   101  func showRawCert(cert ct.ASN1Cert) {
   102  	if textOut {
   103  		c, err := x509.ParseCertificate(cert.Data)
   104  		if err != nil {
   105  			klog.Errorf("Error parsing certificate: %q", err.Error())
   106  		}
   107  		if c == nil {
   108  			return
   109  		}
   110  		showParsedCert(c)
   111  	} else {
   112  		showPEMData(cert.Data)
   113  	}
   114  }
   115  
   116  func showParsedCert(cert *x509.Certificate) {
   117  	if textOut {
   118  		fmt.Printf("%s\n", x509util.CertificateToString(cert))
   119  	} else {
   120  		showPEMData(cert.Raw)
   121  	}
   122  }
   123  
   124  func showPEMData(data []byte) {
   125  	if err := pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: data}); err != nil {
   126  		klog.Errorf("Failed to PEM encode cert: %q", err.Error())
   127  	}
   128  }
   129  

View as plain text