From e0edf35c5368bb9717f51cf8098a127a7b85885d Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Thu, 10 Apr 2025 01:16:01 -0700 Subject: [PATCH] stashing certlib work --- certlib/sct.go | 36 ++++++++++++++++++++++ cmd/certdump/certdump.go | 11 +++++++ cmd/cleankbf/main.go | 65 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 certlib/sct.go create mode 100644 cmd/cleankbf/main.go diff --git a/certlib/sct.go b/certlib/sct.go new file mode 100644 index 0000000..ed397f1 --- /dev/null +++ b/certlib/sct.go @@ -0,0 +1,36 @@ +package certlib + +import ( + "crypto/x509" + "encoding/asn1" + "github.com/davecgh/go-spew/spew" + ct "github.com/google/certificate-transparency-go" +) + +var sctExtension = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} + +// SignedCertificateTimestampList is a list of signed certificate timestamps, from RFC6962 s3.3. +type SignedCertificateTimestampList struct { + SCTList []ct.SignedCertificateTimestamp +} + +func DumpSignedCertificateList(cert *x509.Certificate) ([]ct.SignedCertificateTimestamp, error) { + // x := x509.SignedCertificateTimestampList{} + var sctList []ct.SignedCertificateTimestamp + + for _, extension := range cert.Extensions { + if extension.Id.Equal(sctExtension) { + spew.Dump(extension) + + var rawSCT ct.SignedCertificateTimestamp + _, err := asn1.Unmarshal(extension.Value, &rawSCT) + if err != nil { + return nil, err + } + + sctList = append(sctList, rawSCT) + } + } + + return sctList, nil +} diff --git a/cmd/certdump/certdump.go b/cmd/certdump/certdump.go index de0c66e..4b3609d 100644 --- a/cmd/certdump/certdump.go +++ b/cmd/certdump/certdump.go @@ -214,6 +214,17 @@ func displayCert(cert *x509.Certificate) { wrapPrint(fmt.Sprintf("- %s\n", ocspServer), 2) } } + + fmt.Println("SCTs:") + sctList, err := certlib.DumpSignedCertificateList(cert) + if err != nil { + lib.Warn(err, "failed to dump signed certificate list") + } else { + for _, sct := range sctList { + fmt.Printf("\t- %s\n", sct) + } + } + } func displayAllCerts(in []byte, leafOnly bool) { diff --git a/cmd/cleankbf/main.go b/cmd/cleankbf/main.go new file mode 100644 index 0000000..c87cb5a --- /dev/null +++ b/cmd/cleankbf/main.go @@ -0,0 +1,65 @@ +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "regexp" + + "git.wntrmute.dev/kyle/goutils/die" +) + +var reUUID = regexp.MustCompile(`^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}_(.+)$`) + +func renamePath(path string, dryRun bool) error { + dir, base := filepath.Split(path) + + base = reUUID.ReplaceAllString(base, "$1") + newPath := filepath.Join(dir, base) + + if dryRun { + fmt.Println(path, "->", newPath) + return nil + } + + err := os.Rename(path, newPath) + if err != nil { + return fmt.Errorf("renaming %s to %s failed: %v", path, newPath, err) + } + + return nil +} + +func test() bool { + const testFilePath = "48793683-8568-47c2-9e2d-eecab3c4b639_Whispers of Chernobog.pdf" + const expected = "Whispers of Chernobog.pdf" + + actual := reUUID.ReplaceAllString(testFilePath, "$1") + return actual == expected +} + +func main() { + var err error + + if !test() { + die.With("test failed") + } + + dryRun := false + flag.BoolVar(&dryRun, "n", dryRun, "don't rename files, just print what would be done") + flag.Parse() + + paths := flag.Args() + if len(paths) == 0 { + paths, err = filepath.Glob("*") + die.If(err) + } + + for _, file := range paths { + err = renamePath(file, dryRun) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", file, err) + } + } +}