...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package cmd
16
17 import (
18 "context"
19 "fmt"
20 "time"
21
22 ct "github.com/google/certificate-transparency-go"
23 "github.com/google/certificate-transparency-go/x509"
24 "github.com/google/certificate-transparency-go/x509util"
25 "github.com/spf13/cobra"
26 "k8s.io/klog/v2"
27 )
28
29 var logMMD time.Duration
30
31 func init() {
32 cmd := cobra.Command{
33 Use: fmt.Sprintf("upload %s --cert_chain=file [--log_mmd=dur]", connectionFlags),
34 Aliases: []string{"add-chain"},
35 Short: "Submit a certificate (pre-)chain to the log",
36 Args: cobra.MaximumNArgs(0),
37 Run: func(cmd *cobra.Command, _ []string) {
38 runUpload(cmd.Context())
39 },
40 }
41
42 cmd.Flags().StringVar(&certChain, "cert_chain", "", "Name of file containing certificate chain as concatenated PEM files")
43 cmd.Flags().DurationVar(&logMMD, "log_mmd", 24*time.Hour, "Log's maximum merge delay")
44 rootCmd.AddCommand(&cmd)
45 }
46
47
48 func runUpload(ctx context.Context) {
49 logClient := connect(ctx)
50 if certChain == "" {
51 klog.Exitf("No certificate chain file specified with -cert_chain")
52 }
53 chain, _ := chainFromFile(certChain)
54
55
56 isPrecert := false
57 leaf, err := x509.ParseCertificate(chain[0].Data)
58 if err == nil {
59 count, _ := x509util.OIDInExtensions(x509.OIDExtensionCTPoison, leaf.Extensions)
60 if count > 0 {
61 isPrecert = true
62 fmt.Print("Uploading pre-certificate to log\n")
63 }
64 }
65
66 var sct *ct.SignedCertificateTimestamp
67 if isPrecert {
68 sct, err = logClient.AddPreChain(ctx, chain)
69 } else {
70 sct, err = logClient.AddChain(ctx, chain)
71 }
72 if err != nil {
73 exitWithDetails(err)
74 }
75
76 leafEntry := ct.CreateX509MerkleTreeLeaf(chain[0], sct.Timestamp)
77 leafHash, err := ct.LeafHashForLeaf(leafEntry)
78 if err != nil {
79 klog.Exitf("Failed to create hash of leaf: %v", err)
80 }
81
82
83 when := ct.TimestampToTime(sct.Timestamp)
84 fmt.Printf("Uploaded chain of %d certs to %v log at %v, timestamp: %d (%v)\n", len(chain), sct.SCTVersion, logClient.BaseURI(), sct.Timestamp, when)
85 fmt.Printf("LogID: %x\n", sct.LogID.KeyID[:])
86 fmt.Printf("LeafHash: %x\n", leafHash)
87 fmt.Printf("Signature: %v\n", signatureToString(&sct.Signature))
88
89 age := time.Since(when)
90 if age > logMMD {
91
92 getInclusionProofForHash(ctx, logClient, leafHash[:])
93 }
94 }
95
View as plain text