diff --git a/.github/workflows/codeChecks.yml b/.github/workflows/codeChecks.yml index 55d4230..c080ddd 100644 --- a/.github/workflows/codeChecks.yml +++ b/.github/workflows/codeChecks.yml @@ -5,6 +5,7 @@ on: paths: - ".github/workflows/codeChecks.yml" - ".goreleaser.yaml" + - ".testcoverage.yml" - "devenv.*" - "cmd/**" - "internal/**" @@ -13,13 +14,12 @@ on: - "go.*" jobs: - go_tests: runs-on: ubuntu-latest strategy: max-parallel: 1 matrix: - go-version: ['1.24', '1.25'] + go-version: ["1.25"] steps: - name: Checkout @@ -69,6 +69,23 @@ jobs: run: devenv test timeout-minutes: 15 + go_test_coverage_check: + needs: go_tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-go@v6 + with: + go-version: "1.25" + + - name: generate test coverage + run: go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./... + + - name: check test coverage + uses: vladopajic/go-test-coverage@v2 + with: + config: ./.testcoverage.yml + goreleaser_test: needs: devenv_test runs-on: ubuntu-latest @@ -85,7 +102,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v6 with: - go-version: '1.25' + go-version: "1.25" - name: Run GoReleaser test uses: goreleaser/goreleaser-action@v6 diff --git a/.testcoverage.yml b/.testcoverage.yml new file mode 100644 index 0000000..d3c4bd2 --- /dev/null +++ b/.testcoverage.yml @@ -0,0 +1,12 @@ +profile: cover.out + +threshold: + file: 70 + package: 80 + total: 80 + +exclude: + paths: + - internal/style/style_handlers.go + - main\.go$ + - cmd/main\.go$ diff --git a/cmd/certinfo_test.go b/cmd/certinfo_test.go new file mode 100644 index 0000000..635a6e5 --- /dev/null +++ b/cmd/certinfo_test.go @@ -0,0 +1,124 @@ +package cmd + +import ( + "bytes" + _ "embed" + "testing" + + _ "github.com/breml/rootcerts" + "github.com/stretchr/testify/require" +) + +func TestCertinfoCmd(t *testing.T) { + tests := []struct { + name string + args []string + expectError bool + errMsgs []string + expected []string + }{ + { + name: "no args", + args: []string{"certinfo"}, + expectError: false, + expected: []string{ + "https-wrench certinfo", + "Usage:", + "Flags:", + "Global Flags:", + "--key-file", + "--tls-endpoint", + "--tls-insecure", + "--tls-servername", + "--ca-bundle", + "--version", + "--help", + }, + }, + { + name: "key-file flag no value", + args: []string{"certinfo", "--key-file"}, + expectError: true, + errMsgs: []string{ + "flag needs an argument: --key-file", + }, + expected: []string{ + "https-wrench certinfo [flags]", + "--ca-bundle string", + "--key-file string", + "--tls-endpoint string", + "--tls-insecure", + "--tls-servername string", + "Usage:", + "--version Display the version", + }, + }, + + { + name: "tls-endpoint flag no value", + args: []string{"certinfo", "--tls-endpoint"}, + expectError: true, + errMsgs: []string{ + "flag needs an argument: --tls-endpoint", + }, + expected: []string{ + "https-wrench certinfo [flags]", + "--ca-bundle string", + "--key-file string", + "--tls-endpoint string", + "--tls-insecure", + "--tls-servername string", + "Usage:", + "--version Display the version", + }, + }, + + { + name: "tls-insecure incomplete params", + args: []string{"certinfo", "--tls-insecure"}, + expectError: false, + expected: []string{ + "https-wrench certinfo [flags]", + "--ca-bundle string", + "--key-file string", + "--tls-endpoint string", + "--tls-insecure", + "--tls-servername string", + "Usage:", + "--version Display the version", + }, + }, + } + + for _, tc := range tests { + tt := tc + + t.Run(tt.name, func(t *testing.T) { + reqOut := new(bytes.Buffer) + reqCmd := rootCmd + reqCmd.SetOut(reqOut) + reqCmd.SetErr(reqOut) + reqCmd.SetArgs(tt.args) + err := reqCmd.Execute() + + if tt.expectError { + require.Error(t, err) + + for _, expected := range tt.errMsgs { + require.ErrorContains(t, err, expected) + } + + // return + } + + if !tt.expectError { + require.NoError(t, err) + } + + got := reqOut.String() + for _, expexted := range tt.expected { + require.Contains(t, got, expexted) + } + }) + } +} diff --git a/cmd/config_test.go b/cmd/config_test.go new file mode 100644 index 0000000..9a7a934 --- /dev/null +++ b/cmd/config_test.go @@ -0,0 +1,32 @@ +package cmd + +import ( + _ "embed" + "testing" + + _ "github.com/breml/rootcerts" + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + "github.com/xenos76/https-wrench/internal/requests" +) + +var emptyString = "" + +func TestNewHTTPSWrenchConfig(t *testing.T) { + t.Run("new HTTPSWrenchConfig", func(t *testing.T) { + var mc requests.RequestsMetaConfig + + config := NewHTTPSWrenchConfig() + + require.False(t, config.Debug) + require.False(t, config.Verbose) + require.Equal(t, config.CaBundle, emptyString) + + if diff := cmp.Diff(mc, config.RequestsMetaConfig); diff != "" { + t.Errorf( + "NewHTTPSWrenchConfig: RequestsMetaConfig mismatch (-want +got):\n%s", + diff, + ) + } + }) +} diff --git a/cmd/requests.go b/cmd/requests.go index 2422317..ea74a87 100644 --- a/cmd/requests.go +++ b/cmd/requests.go @@ -45,12 +45,12 @@ Examples: versionRequested := viper.GetBool("version") if versionRequested { - fmt.Print(version) + cmd.Print(version) return } if showSampleConfig { - fmt.Print(sampleYamlConfig) + cmd.Print(sampleYamlConfig) return } diff --git a/cmd/requests_test.go b/cmd/requests_test.go new file mode 100644 index 0000000..ba8fcea --- /dev/null +++ b/cmd/requests_test.go @@ -0,0 +1,141 @@ +package cmd + +import ( + "bytes" + _ "embed" + "testing" + + _ "github.com/breml/rootcerts" + "github.com/stretchr/testify/require" +) + +func TestRequestsCmd(t *testing.T) { + tests := []struct { + name string + args []string + expectError bool + errMsgs []string + expected []string + }{ + { + name: "no args", + args: []string{"requests"}, + expectError: false, + expected: []string{ + "https-wrench requests", + "Usage:", + "Flags:", + "Global Flags:", + "--config", + "--ca-bundle", + "--show-sample-config", + "--version", + "--help", + }, + }, + { + name: "show sample config", + args: []string{"requests", "--show-sample-config"}, + expectError: false, + expected: []string{ + "https-wrench.schema.json", + "requests:", + "transportOverrideUrl:", + "requestHeaders:", + }, + }, + + { + name: "ca-bundle flag no value", + args: []string{"requests", "--ca-bundle"}, + expectError: true, + errMsgs: []string{ + "flag needs an argument: --ca-bundle", + }, + expected: []string{ + "https-wrench requests [flags]", + "--ca-bundle string", + "Usage:", + "--version Display the version", + }, + }, + + { + name: "config flag no file", + args: []string{"requests", "--config"}, + expectError: true, + errMsgs: []string{ + "flag needs an argument: --config", + }, + expected: []string{ + "https-wrench requests [flags]", + "--ca-bundle string", + "Usage:", + "--version Display the version", + }, + }, + + // WARN conflicts with same test for rootCmd + // { + // name: "config flag file not exist", + // args: []string{ + // "requests", + // "--config", + // "/not-existent-file", + // }, + // expectError: false, + // expected: []string{ + // "Config file not found:", + // "https-wrench requests [flags]", + // "--ca-bundle string", + // "Usage:", + // "--version Display the version", + // }, + // }, + // + // WARN conflicts with same test for rootCmd + // { + // name: "version", + // args: []string{"requests", "--version"}, + // expectError: false, + // expected: []string{ + // "https-wrench requests [flags]", + // "--ca-bundle string", + // "Usage:", + // "--version Display the version", + // }, + // }, + } + + for _, tc := range tests { + tt := tc + + t.Run(tt.name, func(t *testing.T) { + reqOut := new(bytes.Buffer) + reqCmd := rootCmd + reqCmd.SetOut(reqOut) + reqCmd.SetErr(reqOut) + reqCmd.SetArgs(tt.args) + err := reqCmd.Execute() + + if tt.expectError { + require.Error(t, err) + + for _, expected := range tt.errMsgs { + require.ErrorContains(t, err, expected) + } + + // return + } + + if !tt.expectError { + require.NoError(t, err) + } + + got := reqOut.String() + for _, expexted := range tt.expected { + require.Contains(t, got, expexted) + } + }) + } +} diff --git a/cmd/root.go b/cmd/root.go index f552bc7..983fc2c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -69,7 +69,7 @@ https://github.com/xenOs76/https-wrench`, Run: func(cmd *cobra.Command, args []string) { showVersion, _ := cmd.Flags().GetBool("version") if showVersion { - fmt.Println(version) + cmd.Println(version) return } diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 0000000..afa7180 --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,88 @@ +package cmd + +import ( + "bytes" + _ "embed" + "testing" + + _ "github.com/breml/rootcerts" + "github.com/stretchr/testify/require" +) + +func TestRootCmd(t *testing.T) { + tests := []struct { + name string + args []string + expectError bool + expected []string + }{ + { + name: "no args", + args: []string{}, + expectError: false, + expected: []string{ + "HTTPS Wrench", + "Usage:", + "Available Commands:", + "Flags:", + "certinfo", + "requests", + "--config", + "--version", + "--help", + }, + }, + + { + name: "config flag not arg", + args: []string{"--config"}, + expectError: true, + expected: []string{"flag needs an argument: --config"}, + }, + { + name: "config flag valid arg", + args: []string{"--config", "./embedded/config-example.yaml"}, + expectError: false, + // Unable to intercept the output + expected: []string{}, + }, + { + name: "version", + args: []string{"--version"}, + expectError: false, + expected: []string{"development"}, + }, + } + + for _, tc := range tests { + tt := tc + t.Run(tt.name, func(t *testing.T) { + buf := new(bytes.Buffer) + rootCmd.SetOut(buf) + rootCmd.SetErr(buf) + rootCmd.SetArgs(tt.args) + + err := rootCmd.Execute() + + if tt.expectError { + require.Error(t, err) + + for _, expected := range tt.expected { + require.ErrorContains(t, err, expected) + } + + return + } + + if !tt.expectError { + require.NoError(t, err) + } + + got := buf.String() + + for _, expected := range tt.expected { + require.Contains(t, got, expected) + } + }) + } +} diff --git a/devenv.lock b/devenv.lock index d34d11d..cd0bf21 100644 --- a/devenv.lock +++ b/devenv.lock @@ -3,10 +3,10 @@ "devenv": { "locked": { "dir": "src/modules", - "lastModified": 1765985825, + "lastModified": 1766843567, "owner": "cachix", "repo": "devenv", - "rev": "51b8b1fc0659b0817dba0f5e40272f86809665ce", + "rev": "d0f2c8545f09e5aba9d321079a284b550371879d", "type": "github" }, "original": { @@ -19,10 +19,10 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1765121682, + "lastModified": 1766661267, "owner": "edolstra", "repo": "flake-compat", - "rev": "65f23138d8d09a92e30f1e5c87611b23ef451bf3", + "rev": "f275e157c50c3a9a682b4c9b4aa4db7a4cd3b5f2", "type": "github" }, "original": { @@ -87,11 +87,27 @@ "type": "github" } }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1766736597, + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f560ccec6b1116b22e6ed15f4c510997d99d5852", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { "devenv": "devenv", "git-hooks": "git-hooks", "nixpkgs": "nixpkgs", + "nixpkgs-stable": "nixpkgs-stable", "pre-commit-hooks": [ "git-hooks" ] diff --git a/devenv.nix b/devenv.nix index d2429a9..03b37f8 100644 --- a/devenv.nix +++ b/devenv.nix @@ -2,8 +2,11 @@ pkgs, lib, config, + inputs, ... -}: { +}: let + pkgs-stable = import inputs.nixpkgs-stable {system = pkgs.stdenv.system;}; +in { env = { GUM_FORMAT_THEME = "tokyo-night"; CAROOT = "tests/certs"; @@ -16,18 +19,23 @@ OS76_DOCKER_USER = "xeno"; }; - languages.go = { - enable = true; - package = pkgs.go; - }; + # WARN installing go from NixOs stable instead + # so the version is aligned with nvim settings + # languages.go = { + # enable = true; + # package = pkgs-stable.go; + # }; packages = with pkgs; [ + pkgs-stable.go git openssl mkcert gum goreleaser govulncheck + gotest + gotests curl jq httpie @@ -41,13 +49,14 @@ ".envrc" "internal/certinfo/common_handlers.go" "internal/certinfo/testdata" + "internal/certinfo/testdata/README.md" "completions" ]; hooks = { shellcheck.enable = true; end-of-file-fixer.enable = true; detect-aws-credentials.enable = false; - detect-private-keys.enable = true; + detect-private-keys.enable = false; ripsecrets.enable = true; commitizen.enable = true; }; @@ -223,17 +232,17 @@ scripts.test-cmd-root-version.exec = '' gum format "## Command root --version" - ./dist/https-wrench --version | grep -E '[0-9]\.+' + ./dist/https-wrench --version 2>&1 | grep -E '[0-9]\.+' ''; scripts.test-cmd-requests-version.exec = '' gum format "## Command requests --version" - ./dist/https-wrench requests --version | grep -E '[0-9]\.+' + ./dist/https-wrench requests --version 2>&1 | grep -E '[0-9]\.+' ''; scripts.test-cmd-certinfo-version.exec = '' gum format "## Command certinfo --version" - ./dist/https-wrench certinfo --version | grep -E '[0-9]\.+' + ./dist/https-wrench certinfo --version 2>&1 | grep -E '[0-9]\.+' ''; scripts.test-cmd-root-help-when-no-flags.exec = '' @@ -583,13 +592,13 @@ scripts.run-go-tests.exec = '' gum format "## Run GO tests" - time go test ./... -cover -coverprofile=cover.out + time gotest ./... -cover -coverprofile=cover.out ''; scripts.run-go-tests-verbose.exec = '' gum format "## Run GO tests" - time go test -v ./... -cover -coverprofile=cover.out + time gotest -v ./... -cover -coverprofile=cover.out ''; scripts.run-go-cover-html.exec = '' diff --git a/devenv.yaml b/devenv.yaml index 6072aac..6a83107 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -3,6 +3,8 @@ inputs: nixpkgs: url: github:cachix/devenv-nixpkgs/rolling + nixpkgs-stable: + url: github:NixOS/nixpkgs/nixos-25.11 # If you're using non-OSS software, you can set allowUnfree to true. # allowUnfree: true diff --git a/go.mod b/go.mod index 06846dc..3ffd6ad 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xenos76/https-wrench -go 1.24.9 +go 1.25.4 require ( github.com/alecthomas/assert/v2 v2.11.0 diff --git a/internal/certinfo/certinfo_handlers.go b/internal/certinfo/certinfo_handlers.go index 2b0ccfe..2275af9 100644 --- a/internal/certinfo/certinfo_handlers.go +++ b/internal/certinfo/certinfo_handlers.go @@ -129,6 +129,7 @@ func (c *CertinfoConfig) PrintData(w io.Writer) error { CertsToTables(w, rootCerts) } + return nil } diff --git a/internal/certinfo/certinfo_handlers_test.go b/internal/certinfo/certinfo_handlers_test.go index 5e85ae9..5de7310 100644 --- a/internal/certinfo/certinfo_handlers_test.go +++ b/internal/certinfo/certinfo_handlers_test.go @@ -165,6 +165,12 @@ func TestCertinfo_CertsToTables(t *testing.T) { ) require.NoError(t, err) + rsaExpiredCert, err := GetCertsFromBundle( + RSASamplePKCS8ExpiredCertificate, + inputReader, + ) + require.NoError(t, err) + ecdsaCert, err := GetCertsFromBundle( ECDSASampleCertificate, inputReader, @@ -187,7 +193,6 @@ func TestCertinfo_CertsToTables(t *testing.T) { publicKeyAlgorithm string signatureAlgorithm string }{ - // TODO: add expired cert case { desc: "RSA CA Cert", cert: RSACaCertParent, @@ -208,6 +213,17 @@ func TestCertinfo_CertsToTables(t *testing.T) { publicKeyAlgorithm: "PublicKeyAlgorithm RSA", signatureAlgorithm: "SignatureAlgorithm SHA256-RSA", }, + { + desc: "RSA Expired Cert", + cert: rsaExpiredCert[0], + subject: "Subject CN=example.com,O=example Ltd,L=Berlin,ST=Some-State,C=DE", + isCA: "IsCA false", + expiration: "ago", + dnsNames: "DNSNames []", + publicKeyAlgorithm: "PublicKeyAlgorithm RSA", + signatureAlgorithm: "SignatureAlgorithm SHA256-RSA", + }, + { desc: "ECDSA CA Cert", cert: ecdsaCert[0], @@ -259,6 +275,7 @@ func TestCertinfo_CertsToTables(t *testing.T) { tt.dnsNames, tt.publicKeyAlgorithm, tt.signatureAlgorithm, + tt.expiration, } { require.Contains(t, got, want) } diff --git a/internal/certinfo/main_test.go b/internal/certinfo/main_test.go index 379c135..b7515ba 100644 --- a/internal/certinfo/main_test.go +++ b/internal/certinfo/main_test.go @@ -67,6 +67,7 @@ var ( RSASamplePKCS8EncBrokenPrivateKey = testdataDir + "/rsa-pkcs8-encrypted-broken-private-key.pem" RSASamplePKCS8Certificate = testdataDir + "/rsa-pkcs8-crt.pem" RSASamplePKCS8BrokenCertificate = testdataDir + "/rsa-pkcs8-broken-crt.pem" + RSASamplePKCS8ExpiredCertificate = testdataDir + "/rsa-pkcs8-expired-crt.pem" ECDSASamplePlaintextPrivateKey = testdataDir + "/ecdsa-plaintext-private-key.pem" ECDSASampleEncryptedPrivateKey = testdataDir + "/ecdsa-encrypted-private-key.pem" diff --git a/internal/certinfo/testdata/README.md b/internal/certinfo/testdata/README.md index f713ff3..2fa7bef 100644 --- a/internal/certinfo/testdata/README.md +++ b/internal/certinfo/testdata/README.md @@ -1,14 +1,14 @@ # Certinfo testdata -Sample private keys generated with Openssl. Plaintext and encrypted versions. -*Warning*: the keys stored in this folder are meant to be used for testing only. +Sample private keys generated with Openssl. Plaintext and encrypted versions. +_Warning_: the keys stored in this folder are meant to be used for testing only. ## Create sample RSA private keys ### PKCS1 -Generating PKCS1 RSA private key with Openssl requires version 1.1.1. -Get it with Nix: +Generating PKCS1 RSA private key with Openssl requires version 1.1.1. Get it +with Nix: ```shell > export NIXPKGS_ALLOW_INSECURE=1 @@ -33,15 +33,15 @@ Verifying - Enter pass phrase for rsa-pkcs1-encrypted-private-key.pem: > head -n 6 rsa-pkcs1-encrypted-private-key.pem -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,314A1EF1E544F10E9741F8A9C57384C8 +(REDACTED) (REDACTED PEM Block) (REDACTED PEM Block) ``` -Decrypt the key: +Decrypt the key: -```shell +```shell > openssl rsa -in rsa-pkcs1-encrypted-private-key.pem -out rsa-pkcs1-plaintext-private-key.pem Enter pass phrase for rsa-pkcs1-encrypted-private-key.pem: writing RSA key @@ -51,14 +51,14 @@ writing RSA key Recent versions of Openssl create private keys in PKCS8 format: -```shell +```shell > openssl version OpenSSL 3.6.0 1 Oct 2025 (Library: OpenSSL 3.6.0 1 Oct 2025 ``` -Create an encrypted key: +Create an encrypted key: -```shell +```shell > openssl genrsa -aes256 -out rsa-pkcs8-encrypted-private-key.pem 4096 Enter PEM pass phrase: Verifying - Enter PEM pass phrase: @@ -69,9 +69,9 @@ Verifying - Enter PEM pass phrase: (REDACTED PEM Block) ``` -Decrypt the key: +Decrypt the key: -```shell +```shell > openssl rsa -in rsa-pkcs8-encrypted-private-key.pem -out rsa-pkcs8-plaintext-private-key.pem Enter pass phrase for rsa-pkcs8-encrypted-private-key.pem: writing RSA key @@ -80,6 +80,7 @@ writing RSA key -----BEGIN PRIVATE KEY----- (REDACTED PEM Block) ``` + ## Create sample RSA certificates Create cert with PKCS1 key: @@ -92,7 +93,7 @@ Create cert with PKCS1 key: Create cert with PKCS8 key: -```shell +```shell > openssl req -new -key rsa-pkcs8-plaintext-private-key.pem -out rsa-pkcs8-csr.pem [...] > openssl x509 -req -days 3650 -in rsa-pkcs8-csr.pem -signkey rsa-pkcs8-plaintext-private-key.pem -out rsa-pkcs8-crt.pem @@ -102,9 +103,9 @@ subject=C=DE, ST=Some-State, L=Berlin, O=example Ltd, CN=example.com ## Create sample ECDSA private keys -Create the plaintext key: +Create the plaintext key: -```shell +```shell > openssl ecparam -name prime256v1 -genkey -noout -out ecdsa-plaintext-private-key.pem > head -n 2 ecdsa-plaintext-private-key.pem @@ -112,15 +113,15 @@ Create the plaintext key: (REDACTED PEM Block) ``` -Encrypt the key: +Encrypt the key: -```shell +```shell > openssl ec -in ecdsa-plaintext-private-key.pem -out ecdsa-encrypted-private-key.pem -aes256 -passout pass:testpassword > head -n 6 ecdsa-encrypted-private-key.pem -----BEGIN EC PRIVATE KEY----- Proc-Type: 4,ENCRYPTED -DEK-Info: AES-256-CBC,B1D5B0AFFB8F76B80B16373F8D81F9C3 +(REDACTED) (REDACTED PEM Block) (REDACTED PEM Block) @@ -128,15 +129,23 @@ DEK-Info: AES-256-CBC,B1D5B0AFFB8F76B80B16373F8D81F9C3 ## Create sample ECDSA certificate +valid 10 years: + ```shell > openssl req -new -x509 -key ecdsa-plaintext-private-key.pem -days 3650 -out ecdsa-crt.pem -subj "/CN=example.com/O=Example Org" ``` +expired: + +```shell +> openssl x509 -req -days 0 -in rsa-pkcs8-csr.pem -signkey rsa-pkcs8-plaintext-private-key.pem -out rsa-pkcs8-expired-crt.pem +``` + ## Create sample ED25519 private keys -Create the plaintext key: +Create the plaintext key: -```shell +```shell > openssl genpkey -algorithm Ed25519 -out ed25519-plaintext-private-key.pem > head -n2 ed25519-plaintext-private-key.pem @@ -144,9 +153,9 @@ Create the plaintext key: (REDACTED PEM Block) ``` -Encrypt the key: +Encrypt the key: -```shell +```shell > openssl pkey -in ed25519-plaintext-private-key.pem -out ed25519-encrypted-private-key.pem -aes256 -passout pass:testpassword > head -n 3 ed25519-encrypted-private-key.pem @@ -154,6 +163,7 @@ Encrypt the key: (REDACTED PEM Block) (REDACTED PEM Block) ``` + ## Create sample ED25519 certificate ```shell diff --git a/internal/certinfo/testdata/rsa-pkcs8-expired-crt.pem b/internal/certinfo/testdata/rsa-pkcs8-expired-crt.pem new file mode 100644 index 0000000..6b38290 --- /dev/null +++ b/internal/certinfo/testdata/rsa-pkcs8-expired-crt.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFbTCCA1WgAwIBAgIURm547/Siej6y+z0vgF3oSrwLTlgwDQYJKoZIhvcNAQEL +BQAwXzELMAkGA1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAcM +BkJlcmxpbjEUMBIGA1UECgwLZXhhbXBsZSBMdGQxFDASBgNVBAMMC2V4YW1wbGUu +Y29tMB4XDTI1MTIxOTA3NTY0MloXDTI1MTIxOTA3NTY0MlowXzELMAkGA1UEBhMC +REUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAcMBkJlcmxpbjEUMBIGA1UE +CgwLZXhhbXBsZSBMdGQxFDASBgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAtjvz7pjc6iXFHeCNEgQ9Fj/wLArQ2Rmuqhe2 +Lqozt4V8fI8euikVECxXHIF0cDoJmdyY9oU71VKW3qDPS0NcB51rUi0iyfoTPXCy +Sig6tkAewbWc03doUifTLSxSmBz5cjdrZIKK8zkQBtdd3A/B7u/ewRXuRA567vN2 +2Gjc5EkrypJUrCWYeFlfcW1UzcbEMag4X3Z3YEmQXppz3EDsm72XZ+KHA3PytKv4 +rPM4IMtQkLMCIpvQ/NdbQXcwYorVo6dszCohqI2uc6hfQ0sbNEsvGX7/PakArNr8 +JkFif5DWS54tXzfzPz3HMbDFyjAURIguHBa6mBCq/tyTQvBNxNu+N+WERMqJjrKk +MQVVbzZLeEov0cINJipI4IC09CqaHa3LUBsvJQmTRoEZJDvtKDmS6qw+eprJIHgU +R5AJ4Is6CddLHUJnPKLoU3pZdsb7a3ks2d4PiHKuRaVJVs5495d/syfZYejB+C+r +9Uyj48p4VuHknJG5JmGtEc9w5pnWdWiGfPJJCSt5C5cZhjDqIkU/g+LrhYULLQRC +yFQ9oDLWo8zGf8xXYDKNutw/qfjBrCLGApNyqW1MibSQf1JNX3sVljDZaR5k20OW +Yd00wqtubq8rw2KgoKV3KOQa/Dkq6SIFg4krbys+DqnZ2XKtL+Bq1OpAu558A76S +zKjpKT8CAwEAAaMhMB8wHQYDVR0OBBYEFAjuAcgUUDpC4pmbUICqf9TYnsXEMA0G +CSqGSIb3DQEBCwUAA4ICAQCCCy84LYWzQhXqMZw3eQKHnB8BengqPBLNKAtZGVeH +QDPfMOfwrhqzNeOlInUPdldM9ZknyI9wmAOdmN9jzxAoj7X0U6tpCJWvGr8D3UV0 +Hh39/Nm3hjKRUGLikALvXYoMOCNTj2NJt8APAs55QU3Qm1oHpM6mf3ypNeB/qFKB +FKKWUly4Ydkc3SXHS8lQKGxgdDCSDf/2iIWc4Mo1RoXC20YJ6jTgsgZskxw+2Tlz +Id22/h4HRz+1FDNGRex+0jF1eLgFVic3YR9zSkHxanlWoPc4EE/yefNDQd1yAr57 +XZ6SoOEZesaqwnk6LGT0Y4WuTorqkRP+S5vGKGqlmxSx4AC1Yrtv4VQA0MCRCH/r +VnY3PUWjOpe7CM4gzIt4wh4k8CgZferUgEXu0NlRpvV/jiHD22Mx4op9Xe/0Iwp0 +I1xbqeQTox03cS6jhvA+lbCBzOoJdg5Mhbxz358qMB34+7hT8eYzOJUzTOz8wKAy +QKZCnIoU0HCpBsr8Qf/NoUUE9ppv+PfpG2ts+3m5EuJ7oLI1S5DIrYa+M0LzfACR +mSCC9KOQmdtiIhEyxQNvi9SfPkSYP5tVd9gWWbYUa4g5xlZbMAI7iKdb0neUpyAN +CWo/IIO9+mco11nU41LZNlZ9qcyM0CrKax1uNDmic5pwd3HZIJcJ1jysTyMgFtWS +qw== +-----END CERTIFICATE-----