Skip to content

Commit 3cf9b71

Browse files
committed
Implemented certificate info
1 parent 551d8c2 commit 3cf9b71

4 files changed

Lines changed: 100 additions & 10 deletions

File tree

cert_auth.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@ import (
1818
"time"
1919
)
2020

21+
var commonNameCA = "Devcert Certificate Authority (CA)"
22+
2123
// CA represents a certificate authority cert and private key.
2224
type CA struct {
2325
Valid bool
2426
Cert *x509.Certificate
2527
PrivKey *rsa.PrivateKey
2628
}
2729

30+
31+
2832
func buildCAPaths() (crtPath, keyPath string, err error) {
2933
devcertDir, err := buildDevcertDir()
3034
if err != nil {
@@ -184,7 +188,7 @@ func generateCA() (err error) {
184188
ca := &x509.Certificate{
185189
SerialNumber: big.NewInt(mrand.Int63()),
186190
Subject: pkix.Name{
187-
CommonName: "Devcert Certificate Authority (CA)",
191+
CommonName: commonNameCA,
188192
},
189193
NotBefore: time.Now(),
190194
NotAfter: time.Now().AddDate(5, 0, 0),

cert_info.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package main
2+
3+
import (
4+
"crypto/x509"
5+
"encoding/pem"
6+
"errors"
7+
"fmt"
8+
"os"
9+
"strconv"
10+
"strings"
11+
)
12+
13+
func devcertInfo(args []string) (err error) {
14+
filename := args[0]
15+
16+
cb, err := os.ReadFile(filename)
17+
if err != nil {
18+
return
19+
}
20+
21+
certBlock, _ := pem.Decode(cb)
22+
if certBlock == nil || certBlock.Type != "CERTIFICATE" {
23+
err = errors.New("invalid certificate")
24+
return
25+
}
26+
27+
cert, err := x509.ParseCertificate(certBlock.Bytes)
28+
if err != nil {
29+
return
30+
}
31+
32+
isCAHuman := "No"
33+
if cert.IsCA {
34+
isCAHuman = "Yes"
35+
}
36+
37+
isDevcertHuman := "No"
38+
if cert.Issuer.CommonName == commonNameCA {
39+
isDevcertHuman = "Yes"
40+
}
41+
42+
fmt.Printf("\nCertificate Info:")
43+
fmt.Printf("\n - Is CA: %s", isCAHuman)
44+
fmt.Printf("\n - Generated by devcert: %s", isDevcertHuman)
45+
fmt.Printf("\n - Issuer: %s", cert.Issuer.CommonName)
46+
47+
if !cert.IsCA {
48+
fmt.Printf("\n - Domain(s): %s", strings.Join(cert.DNSNames, ", "))
49+
}
50+
51+
fmt.Printf("\n - Signature Algorithm: %s", cert.SignatureAlgorithm)
52+
fmt.Printf("\n - Version: %s", strconv.Itoa(cert.Version))
53+
fmt.Printf("\n - Valid Until: %s", cert.NotAfter)
54+
55+
fmt.Printf("\n")
56+
57+
return
58+
}

main.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,39 @@ package main
22

33
import (
44
"fmt"
5-
"github.com/spf13/cobra"
65
"os"
6+
7+
"github.com/spf13/cobra"
78
)
89

910
func main() {
1011

1112
var rootCmd = &cobra.Command{
1213
Use: "devcert [space separated domain names]",
1314
Short: "Self-signed trusted certificates for local development.",
14-
Long: `Generate self-signed, trusted certificates for local development.
15-
Devcert takes away the pain of creating certificates for development manually.`,
15+
Long: `Generate self-signed, trusted certificates for local development.`,
1616
Args: cobra.MinimumNArgs(1),
1717
RunE: func(cmd *cobra.Command, args []string) error {
18-
err := devcertExec(args)
19-
if err != nil {
20-
return err
21-
}
22-
return nil
18+
err := devcertExec(args)
19+
return err
20+
},
21+
}
22+
23+
var infoCmd = &cobra.Command{
24+
Use: "info [.crt file]",
25+
Short: "Print the certificate information.",
26+
Long: "Print out the certificate information that the .crt file contains.",
27+
Args: cobra.ExactArgs(1),
28+
RunE: func(cmd *cobra.Command, args[]string) error {
29+
err := devcertInfo(args)
30+
return err
2331
},
2432
}
2533

34+
// Add the info command to the CLI commands
35+
rootCmd.AddCommand(infoCmd)
36+
37+
2638
err := rootCmd.Execute()
2739
if err != nil {
2840
fmt.Fprintf(os.Stderr, err.Error())

readme.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Clone this repo and compile from source using Go.
2121

2222
### Install a pre-built binary
2323

24-
1. Download the binary for your platform, example macOS ARM: `curl https://github.com/primalskill/devcert/releases/download/v1.1.2/devcert_darwin_arm64 > /usr/local/bin/devcert`
24+
1. Download the binary for your platform, example macOS ARM: `curl https://github.com/primalskill/devcert/releases/download/v1.2.0/devcert_darwin_arm64 > /usr/local/bin/devcert`
2525
2. Make it an executable: `chmod +x /usr/local/bin`
2626
3. Generate a certificate for a local domain (see the detailed usage below): `devcert example.test`
2727

@@ -68,6 +68,22 @@ Valid for:
6868

6969
You can move the `.crt` and `.key` files to your desired location. It will be signed with the CA, no need to trust this certificate separately.
7070

71+
## Certificate Info
72+
73+
You can get information on a crt file by executing the following command.
74+
75+
```
76+
$ devcert info path/to/crt/file.crt
77+
78+
Certificate Info:
79+
- Is CA: No
80+
- Generated by devcert: Yes
81+
- Issuer: Devcert Certificate Authority (CA)
82+
- Domain(s): example.test, api.example.test
83+
- Signature Algorithm: SHA256-RSA
84+
- Version: 3
85+
- Valid Until: 2024-06-16 11:08:30 +0000 UTC
86+
```
7187
## On First Run
7288

7389
When running the program for the first time, it will ask for running the setup process which creates the necessary directory, generate the CA and mark it as trusted.

0 commit comments

Comments
 (0)