Skip to content

Commit

Permalink
add feature for show cert info
Browse files Browse the repository at this point in the history
  • Loading branch information
nothinux committed Mar 5, 2022
1 parent cbe23e6 commit 8508ac7
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 3 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ $ certify server.local expiry:1d
$ certify cn:web-server
⚡️ Generate certificate with common name web-server
Also, you can see information from created certificate
$ certify -show server.local.pem
⚡️ Show information from certificate with name server.local.pem
```

## Use Certify as library
Expand Down
50 changes: 50 additions & 0 deletions certify.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"fmt"
"math/big"
"net"
"strings"
"time"
)

Expand Down Expand Up @@ -109,3 +110,52 @@ func ParseCertificate(cert []byte) (*x509.Certificate, error) {

return c, nil
}

func CertInfo(cert *x509.Certificate) string {
var buf bytes.Buffer

buf.WriteString("Certificate\n")
buf.WriteString(fmt.Sprintf("%4sData:\n", ""))
buf.WriteString(fmt.Sprintf("%8sVersion: %d\n", "", cert.Version))
buf.WriteString(fmt.Sprintf("%8sSerial Number:\n%12s%v\n", "", "", formatKeyIDWithColon(cert.SerialNumber.Bytes())))
buf.WriteString(fmt.Sprintf("%8sSignature Algorithm: %v\n", "", cert.SignatureAlgorithm))

buf.WriteString(fmt.Sprintf("%8sIssuer: %v\n", "", strings.Replace(cert.Issuer.String(), ",", ", ", -1)))

buf.WriteString(fmt.Sprintf("%8sValidity:\n", ""))
buf.WriteString(fmt.Sprintf("%12sNotBefore: %v\n", "", cert.NotBefore.Format("Jan 2 15:04:05 2006 GMT")))
buf.WriteString(fmt.Sprintf("%12sNotAfter : %v\n", "", cert.NotAfter.Format("Jan 2 15:04:05 2006 GMT")))

buf.WriteString(fmt.Sprintf("%8sSubject: %v\n", "", strings.Replace(cert.Subject.String(), ",", ", ", -1)))

if cert.PublicKeyAlgorithm == x509.ECDSA {
buf.WriteString(fmt.Sprintf("%8sSubject Public Key Info:\n", ""))
buf.WriteString(fmt.Sprintf("%12sPublic Key Algorithm: %v\n", "", cert.PublicKeyAlgorithm))

if ecdsakey, ok := cert.PublicKey.(*ecdsa.PublicKey); ok {
buf.WriteString(fmt.Sprintf("%16sPublic Key: (%d bit)\n", "", ecdsakey.Params().BitSize))
buf.WriteString(fmt.Sprintf("%16sNIST Curve: %s\n", "", ecdsakey.Params().Name))
}
}

buf.WriteString(fmt.Sprintf("%8sX509v3 extensions:\n", ""))
buf.WriteString(fmt.Sprintf("%12sX509v3 Extended Key Usage:\n", ""))
buf.WriteString(fmt.Sprintf("%16s%v\n", "", parseExtKeyUsage(cert.ExtKeyUsage)))
buf.WriteString(fmt.Sprintf("%8sX509v3 Basic Constraints:\n", ""))
buf.WriteString(fmt.Sprintf("%12sCA: %v\n", "", cert.IsCA))
buf.WriteString(fmt.Sprintf("%8sX509v3 Subject Alternative Name:\n", ""))
if len(cert.IPAddresses) != 0 {
var ips []string
for _, ip := range cert.IPAddresses {
ips = append(ips, ip.String())
}
buf.WriteString(fmt.Sprintf("%12sIP Address: %v\n", "", strings.Join(ips, ", ")))
}
if len(cert.DNSNames) != 0 {
buf.WriteString(fmt.Sprintf("%12sDNS: %v\n", "", strings.Join(cert.DNSNames, ", ")))
}

buf.WriteString(fmt.Sprintf("%8sSignature Algorithm: %v\n", "", cert.SignatureAlgorithm))

return buf.String()
}
35 changes: 35 additions & 0 deletions certify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package certify

import (
"crypto/x509/pkix"
"fmt"
"net"
"testing"
"time"
Expand Down Expand Up @@ -67,3 +68,37 @@ func TestGetCertificate(t *testing.T) {
})

}

func TestCertInfo(t *testing.T) {
pkey, err := GetPrivateKey()
if err != nil {
t.Fatal(err)
}

template := Certificate{
Subject: pkix.Name{
Organization: []string{"certify"},
CommonName: "certify",
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
IsCA: true,
DNSNames: []string{"github.com"},
IPAddress: []net.IP{
net.ParseIP("127.0.0.1"),
},
}

res, err := template.GetCertificate(pkey.PrivateKey)
if err != nil {
t.Fatal(err)
}

cert, err := ParseCertificate([]byte(res.String()))
if err != nil {
t.Fatal(err)
}

s := CertInfo(cert)
fmt.Println(s)
}
32 changes: 29 additions & 3 deletions cmd/certify/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"log"
"os"
"strings"

"github.com/nothinux/certify"
)

const usage = `Usage of certify:
Expand All @@ -17,13 +19,16 @@ $ certify -init
$ certify server.local 172.17.0.1
⚡️ Generate certificate with alt name server.local and 172.17.0.1
$ certify cn:web-server
⚡️ Generate certificate with common name web-server
$ certify server.local expiry:1d
⚡️ Generate certificate expiry within 1 day
Also you can set subject common name by providing cn:yourcn
Also, you can see information from created certificate
$ certify cn:web-server
⚡️ Generate certificate with common name web-server
$ certify -show server.local.pem
⚡️ Show information from certificate with name server.local.pem
You must create new CA by run -init before you can create certificate.
`
Expand All @@ -35,6 +40,7 @@ var (

func main() {
init := flag.Bool("init", false, "initialize new CA Certificate and Key")
show := flag.Bool("show", false, "show information about certificate")
flag.Usage = func() {
fmt.Fprint(flag.CommandLine.Output(), usage)
}
Expand Down Expand Up @@ -62,6 +68,26 @@ func main() {
return
}

if *show {
if len(os.Args) < 3 {
fmt.Printf("you must provide certificate path.\n")
os.Exit(1)
}

f, err := os.ReadFile(os.Args[2])
if err != nil {
log.Fatal(err)
}

cert, err := certify.ParseCertificate(f)
if err != nil {
log.Fatal(err)
}

fmt.Printf("%s", certify.CertInfo(cert))
return
}

if len(os.Args) < 2 {
fmt.Printf("you must provide at least two argument.\n\n")
fmt.Fprint(flag.CommandLine.Output(), usage)
Expand Down
39 changes: 39 additions & 0 deletions helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package certify

import (
"crypto/x509"
"fmt"
"strconv"
"strings"
)

func parseExtKeyUsage(ekus []x509.ExtKeyUsage) string {
var extku []string

for _, eku := range ekus {
if eku == x509.ExtKeyUsageAny {
extku = append(extku, "ExtKeyUsageAny")
} else if eku == x509.ExtKeyUsageClientAuth {
extku = append(extku, "ExtKeyUsageClientAuth")
} else if eku == x509.ExtKeyUsageServerAuth {
extku = append(extku, "ExtKeyUsageServerAuth")
} else {
extku = append(extku, strconv.Itoa(int(eku)))
}
}

return strings.Join(extku, ", ")
}

func formatKeyIDWithColon(id []byte) string {
var s string

for i, c := range id {
if i > 0 {
s += ":"
}
s += fmt.Sprintf("%02x", c)
}

return s
}

0 comments on commit 8508ac7

Please sign in to comment.