This commit is contained in:
2025-11-18 12:35:59 -08:00
parent d11e0cf9f9
commit d34a417dce
6 changed files with 612 additions and 143 deletions

35
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch: {}
permissions:
contents: write
jobs:
goreleaser:
name: GoReleaser
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
cache: true
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
cmd/cert-bundler/testdata/pkg/* cmd/cert-bundler/testdata/pkg/*
# Added by goreleaser init: # Added by goreleaser init:
dist/ dist/
cmd/cert-bundler/testdata/bundle/

447
.goreleaser.yaml Normal file
View File

@@ -0,0 +1,447 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- id: atping
main: ./cmd/atping/main.go
binary: atping
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: ca-signed
main: ./cmd/ca-signed/main.go
binary: ca-signed
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: cert-bundler
main: ./cmd/cert-bundler/main.go
binary: cert-bundler
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: cert-revcheck
main: ./cmd/cert-revcheck/main.go
binary: cert-revcheck
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: certchain
main: ./cmd/certchain/main.go
binary: certchain
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: certdump
main: ./cmd/certdump/main.go
binary: certdump
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: certexpiry
main: ./cmd/certexpiry/main.go
binary: certexpiry
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: certser
main: ./cmd/certser/main.go
binary: certser
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: certverify
main: ./cmd/certverify/main.go
binary: certverify
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: clustersh
main: ./cmd/clustersh/main.go
binary: clustersh
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: cruntar
main: ./cmd/cruntar/main.go
binary: cruntar
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: csrpubdump
main: ./cmd/csrpubdump/main.go
binary: csrpubdump
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: data_sync
main: ./cmd/data_sync/main.go
binary: data_sync
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: diskimg
main: ./cmd/diskimg/main.go
binary: diskimg
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: dumpbytes
main: ./cmd/dumpbytes/main.go
binary: dumpbytes
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: eig
main: ./cmd/eig/main.go
binary: eig
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: fragment
main: ./cmd/fragment/main.go
binary: fragment
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: host
main: ./cmd/host/main.go
binary: host
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: jlp
main: ./cmd/jlp/main.go
binary: jlp
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: kgz
main: ./cmd/kgz/main.go
binary: kgz
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: minmax
main: ./cmd/minmax/main.go
binary: minmax
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: parts
main: ./cmd/parts/main.go
binary: parts
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: pem2bin
main: ./cmd/pem2bin/main.go
binary: pem2bin
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: pembody
main: ./cmd/pembody/main.go
binary: pembody
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: pemit
main: ./cmd/pemit/main.go
binary: pemit
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: readchain
main: ./cmd/readchain/main.go
binary: readchain
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: renfnv
main: ./cmd/renfnv/main.go
binary: renfnv
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: rhash
main: ./cmd/rhash/main.go
binary: rhash
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: rolldie
main: ./cmd/rolldie/main.go
binary: rolldie
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: showimp
main: ./cmd/showimp/main.go
binary: showimp
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: ski
main: ./cmd/ski/main.go
binary: ski
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: sprox
main: ./cmd/sprox/main.go
binary: sprox
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: stealchain
main: ./cmd/stealchain/main.go
binary: stealchain
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: stealchain-server
main: ./cmd/stealchain-server/main.go
binary: stealchain-server
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: subjhash
main: ./cmd/subjhash/main.go
binary: subjhash
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: tlsinfo
main: ./cmd/tlsinfo/main.go
binary: tlsinfo
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: tlskeypair
main: ./cmd/tlskeypair/main.go
binary: tlskeypair
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: utc
main: ./cmd/utc/main.go
binary: utc
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: yamll
main: ./cmd/yamll/main.go
binary: yamll
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
- id: zsearch
main: ./cmd/zsearch/main.go
binary: zsearch
env:
- CGO_ENABLED=0
goos: [linux, darwin]
goarch: [amd64, arm64]
ignore:
- goos: darwin
goarch: amd64
archives:
- formats: [tar.gz]
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
formats: [zip]
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
release:
footer: >-
---
Released by [GoReleaser](https://github.com/goreleaser/goreleaser).

View File

@@ -91,7 +91,7 @@ func TestReset(t *testing.T) {
} }
} }
const decay = 25 * time.Millisecond const decay = time.Second
const maxDuration = 10 * time.Millisecond const maxDuration = 10 * time.Millisecond
const interval = time.Millisecond const interval = time.Millisecond

View File

@@ -15,10 +15,138 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/kr/text"
"git.wntrmute.dev/kyle/goutils/certlib" "git.wntrmute.dev/kyle/goutils/certlib"
"git.wntrmute.dev/kyle/goutils/lib" "git.wntrmute.dev/kyle/goutils/lib"
) )
// following two lifted from CFSSL, (replace-regexp "\(.+\): \(.+\),"
// "\2: \1,")
const (
sSHA256 = "SHA256"
sSHA512 = "SHA512"
)
var keyUsage = map[x509.KeyUsage]string{
x509.KeyUsageDigitalSignature: "digital signature",
x509.KeyUsageContentCommitment: "content committment",
x509.KeyUsageKeyEncipherment: "key encipherment",
x509.KeyUsageKeyAgreement: "key agreement",
x509.KeyUsageDataEncipherment: "data encipherment",
x509.KeyUsageCertSign: "cert sign",
x509.KeyUsageCRLSign: "crl sign",
x509.KeyUsageEncipherOnly: "encipher only",
x509.KeyUsageDecipherOnly: "decipher only",
}
var extKeyUsages = map[x509.ExtKeyUsage]string{
x509.ExtKeyUsageAny: "any",
x509.ExtKeyUsageServerAuth: "server auth",
x509.ExtKeyUsageClientAuth: "client auth",
x509.ExtKeyUsageCodeSigning: "code signing",
x509.ExtKeyUsageEmailProtection: "s/mime",
x509.ExtKeyUsageIPSECEndSystem: "ipsec end system",
x509.ExtKeyUsageIPSECTunnel: "ipsec tunnel",
x509.ExtKeyUsageIPSECUser: "ipsec user",
x509.ExtKeyUsageTimeStamping: "timestamping",
x509.ExtKeyUsageOCSPSigning: "ocsp signing",
x509.ExtKeyUsageMicrosoftServerGatedCrypto: "microsoft sgc",
x509.ExtKeyUsageNetscapeServerGatedCrypto: "netscape sgc",
x509.ExtKeyUsageMicrosoftCommercialCodeSigning: "microsoft commercial code signing",
x509.ExtKeyUsageMicrosoftKernelCodeSigning: "microsoft kernel code signing",
}
func sigAlgoPK(a x509.SignatureAlgorithm) string {
switch a {
case x509.MD2WithRSA, x509.MD5WithRSA, x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA:
return "RSA"
case x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS:
return "RSA-PSS"
case x509.ECDSAWithSHA1, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512:
return "ECDSA"
case x509.DSAWithSHA1, x509.DSAWithSHA256:
return "DSA"
case x509.PureEd25519:
return "Ed25519"
case x509.UnknownSignatureAlgorithm:
return "unknown public key algorithm"
default:
return "unknown public key algorithm"
}
}
func sigAlgoHash(a x509.SignatureAlgorithm) string {
switch a {
case x509.MD2WithRSA:
return "MD2"
case x509.MD5WithRSA:
return "MD5"
case x509.SHA1WithRSA, x509.ECDSAWithSHA1, x509.DSAWithSHA1:
return "SHA1"
case x509.SHA256WithRSA, x509.ECDSAWithSHA256, x509.DSAWithSHA256:
return sSHA256
case x509.SHA256WithRSAPSS:
return sSHA256
case x509.SHA384WithRSA, x509.ECDSAWithSHA384:
return "SHA384"
case x509.SHA384WithRSAPSS:
return "SHA384"
case x509.SHA512WithRSA, x509.ECDSAWithSHA512:
return sSHA512
case x509.SHA512WithRSAPSS:
return sSHA512
case x509.PureEd25519:
return sSHA512
case x509.UnknownSignatureAlgorithm:
return "unknown hash algorithm"
default:
return "unknown hash algorithm"
}
}
const maxLine = 78
func makeIndent(n int) string {
s := " "
var sSb97 strings.Builder
for range n {
sSb97.WriteString(" ")
}
s += sSb97.String()
return s
}
func indentLen(n int) int {
return 4 + (8 * n)
}
// this isn't real efficient, but that's not a problem here.
func wrap(s string, indent int) string {
if indent > 3 {
indent = 3
}
wrapped := text.Wrap(s, maxLine)
lines := strings.SplitN(wrapped, "\n", 2)
if len(lines) == 1 {
return lines[0]
}
if (maxLine - indentLen(indent)) <= 0 {
panic("too much indentation")
}
rest := strings.Join(lines[1:], " ")
wrapped = text.Wrap(rest, maxLine-indentLen(indent))
return lines[0] + "\n" + text.Indent(wrapped, makeIndent(indent))
}
func dumpHex(in []byte) string {
return lib.HexEncode(in, lib.HexEncodeUpperColon)
}
func certPublic(cert *x509.Certificate) string { func certPublic(cert *x509.Certificate) string {
switch pub := cert.PublicKey.(type) { switch pub := cert.PublicKey.(type) {
case *rsa.PublicKey: case *rsa.PublicKey:

View File

@@ -1,142 +0,0 @@
package main
import (
"crypto/x509"
"fmt"
"strings"
"github.com/kr/text"
)
// following two lifted from CFSSL, (replace-regexp "\(.+\): \(.+\),"
// "\2: \1,")
const (
sSHA256 = "SHA256"
sSHA512 = "SHA512"
)
var keyUsage = map[x509.KeyUsage]string{
x509.KeyUsageDigitalSignature: "digital signature",
x509.KeyUsageContentCommitment: "content committment",
x509.KeyUsageKeyEncipherment: "key encipherment",
x509.KeyUsageKeyAgreement: "key agreement",
x509.KeyUsageDataEncipherment: "data encipherment",
x509.KeyUsageCertSign: "cert sign",
x509.KeyUsageCRLSign: "crl sign",
x509.KeyUsageEncipherOnly: "encipher only",
x509.KeyUsageDecipherOnly: "decipher only",
}
var extKeyUsages = map[x509.ExtKeyUsage]string{
x509.ExtKeyUsageAny: "any",
x509.ExtKeyUsageServerAuth: "server auth",
x509.ExtKeyUsageClientAuth: "client auth",
x509.ExtKeyUsageCodeSigning: "code signing",
x509.ExtKeyUsageEmailProtection: "s/mime",
x509.ExtKeyUsageIPSECEndSystem: "ipsec end system",
x509.ExtKeyUsageIPSECTunnel: "ipsec tunnel",
x509.ExtKeyUsageIPSECUser: "ipsec user",
x509.ExtKeyUsageTimeStamping: "timestamping",
x509.ExtKeyUsageOCSPSigning: "ocsp signing",
x509.ExtKeyUsageMicrosoftServerGatedCrypto: "microsoft sgc",
x509.ExtKeyUsageNetscapeServerGatedCrypto: "netscape sgc",
x509.ExtKeyUsageMicrosoftCommercialCodeSigning: "microsoft commercial code signing",
x509.ExtKeyUsageMicrosoftKernelCodeSigning: "microsoft kernel code signing",
}
func sigAlgoPK(a x509.SignatureAlgorithm) string {
switch a {
case x509.MD2WithRSA, x509.MD5WithRSA, x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA:
return "RSA"
case x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS:
return "RSA-PSS"
case x509.ECDSAWithSHA1, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512:
return "ECDSA"
case x509.DSAWithSHA1, x509.DSAWithSHA256:
return "DSA"
case x509.PureEd25519:
return "Ed25519"
case x509.UnknownSignatureAlgorithm:
return "unknown public key algorithm"
default:
return "unknown public key algorithm"
}
}
func sigAlgoHash(a x509.SignatureAlgorithm) string {
switch a {
case x509.MD2WithRSA:
return "MD2"
case x509.MD5WithRSA:
return "MD5"
case x509.SHA1WithRSA, x509.ECDSAWithSHA1, x509.DSAWithSHA1:
return "SHA1"
case x509.SHA256WithRSA, x509.ECDSAWithSHA256, x509.DSAWithSHA256:
return sSHA256
case x509.SHA256WithRSAPSS:
return sSHA256
case x509.SHA384WithRSA, x509.ECDSAWithSHA384:
return "SHA384"
case x509.SHA384WithRSAPSS:
return "SHA384"
case x509.SHA512WithRSA, x509.ECDSAWithSHA512:
return sSHA512
case x509.SHA512WithRSAPSS:
return sSHA512
case x509.PureEd25519:
return sSHA512
case x509.UnknownSignatureAlgorithm:
return "unknown hash algorithm"
default:
return "unknown hash algorithm"
}
}
const maxLine = 78
func makeIndent(n int) string {
s := " "
var sSb97 strings.Builder
for range n {
sSb97.WriteString(" ")
}
s += sSb97.String()
return s
}
func indentLen(n int) int {
return 4 + (8 * n)
}
// this isn't real efficient, but that's not a problem here.
func wrap(s string, indent int) string {
if indent > 3 {
indent = 3
}
wrapped := text.Wrap(s, maxLine)
lines := strings.SplitN(wrapped, "\n", 2)
if len(lines) == 1 {
return lines[0]
}
if (maxLine - indentLen(indent)) <= 0 {
panic("too much indentation")
}
rest := strings.Join(lines[1:], " ")
wrapped = text.Wrap(rest, maxLine-indentLen(indent))
return lines[0] + "\n" + text.Indent(wrapped, makeIndent(indent))
}
func dumpHex(in []byte) string {
var s string
var sSb130 strings.Builder
for i := range in {
sSb130.WriteString(fmt.Sprintf("%02X:", in[i]))
}
s += sSb130.String()
return strings.Trim(s, ":")
}