mirror of
https://github.com/square/certigo.git
synced 2024-04-21 12:32:40 +00:00
Make text certs shorter, existing text output now has a --verbose flag
This commit is contained in:
+46
-13
@@ -26,15 +26,13 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"encoding/asn1"
|
||||
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
var layout = `
|
||||
var verboseLayout = `
|
||||
{{- define "PkixName" -}}
|
||||
{{- range .Names}}
|
||||
{{ .Type | oidify }}: {{ .Value }}
|
||||
{{ .Type | oidName }}: {{ .Value }}
|
||||
{{- end -}}
|
||||
{{end -}}
|
||||
|
||||
@@ -66,6 +64,39 @@ Email Addresses:{{range .EmailAddresses}}
|
||||
Warnings:{{range .Warnings}}
|
||||
{{. | redify}}{{end}}{{end}}`
|
||||
|
||||
var layout = `
|
||||
{{- define "PkixName" -}}
|
||||
{{- range $index, $element := .Names}}
|
||||
{{- if $index}}, {{end}}
|
||||
{{- $short := $element.Type | oidShort }}
|
||||
{{- if $short -}}
|
||||
{{ $short }}={{ .Value }}
|
||||
{{- end}}
|
||||
{{- end -}}
|
||||
{{end -}}
|
||||
|
||||
{{- if .Alias}}{{.Alias}}
|
||||
{{end -}}
|
||||
Not Before: {{.NotBefore | certStart}}
|
||||
Not After : {{.NotAfter | certEnd}}
|
||||
Subject: {{template "PkixName" .Subject.Name}}
|
||||
Issuer: {{template "PkixName" .Issuer.Name}}
|
||||
{{- if .NameConstraints}}
|
||||
Name Constraints {{if .PermittedDNSDomains.Critical}}(critical){{end}}: {{range .NameConstraints.PermittedDNSDomains}}
|
||||
{{.}}{{end}}{{end}}
|
||||
{{- if .AltDNSNames}}
|
||||
Alternate DNS Names:{{range .AltDNSNames}}
|
||||
{{.}}{{end}}{{end}}
|
||||
{{- if .AltIPAddresses}}
|
||||
Alternate IP Addresses:{{range .AltIPAddresses}}
|
||||
{{.}}{{end}}{{end}}
|
||||
{{- if .EmailAddresses}}
|
||||
Email Addresses:{{range .EmailAddresses}}
|
||||
{{.}}{{end}}{{end}}
|
||||
{{- if .Warnings}}
|
||||
Warnings:{{range .Warnings}}
|
||||
{{. | redify}}{{end}}{{end}}`
|
||||
|
||||
type certWithName struct {
|
||||
name string
|
||||
file string
|
||||
@@ -110,15 +141,15 @@ func EncodeX509ToObject(cert *x509.Certificate) interface{} {
|
||||
}
|
||||
|
||||
// EncodeX509ToText encodes an X.509 certificate into human-readable text.
|
||||
func EncodeX509ToText(cert *x509.Certificate) []byte {
|
||||
return displayCert(createSimpleCertificate("", cert))
|
||||
func EncodeX509ToText(cert *x509.Certificate, verbose bool) []byte {
|
||||
return displayCert(createSimpleCertificate("", cert), verbose)
|
||||
}
|
||||
|
||||
// displayCert takes in a parsed certificate object
|
||||
// (for jceks certs, blank otherwise), and prints out relevant
|
||||
// information. Start and end dates are colored based on whether or not
|
||||
// the certificate is expired, not expired, or close to expiring.
|
||||
func displayCert(cert simpleCertificate) []byte {
|
||||
func displayCert(cert simpleCertificate, verbose bool) []byte {
|
||||
funcMap := template.FuncMap{
|
||||
"certStart": certStart,
|
||||
"certEnd": certEnd,
|
||||
@@ -127,10 +158,16 @@ func displayCert(cert simpleCertificate) []byte {
|
||||
"hexify": hexify,
|
||||
"keyUsage": keyUsage,
|
||||
"extKeyUsage": extKeyUsage,
|
||||
"oidify": oidify,
|
||||
"oidName": oidName,
|
||||
"oidShort": oidShort,
|
||||
}
|
||||
t := template.New("Cert template").Funcs(funcMap)
|
||||
t, err := t.Parse(layout)
|
||||
var err error
|
||||
if verbose {
|
||||
t, err = t.Parse(verboseLayout)
|
||||
} else {
|
||||
t, err = t.Parse(layout)
|
||||
}
|
||||
if err != nil {
|
||||
// Should never happen
|
||||
panic(err)
|
||||
@@ -221,7 +258,3 @@ func certEnd(end time.Time) string {
|
||||
func redify(text string) string {
|
||||
return red.SprintfFunc()("%s", text)
|
||||
}
|
||||
|
||||
func oidify(oid asn1.ObjectIdentifier) string {
|
||||
return describeOid(oid).Name
|
||||
}
|
||||
|
||||
+23
-14
@@ -2,10 +2,11 @@ package lib
|
||||
|
||||
import "encoding/asn1"
|
||||
|
||||
// OidDescription returns a human-readable name, a snake_case slug suitable as a json key,
|
||||
// OidDescription returns a human-readable name, a short acronym from RFC1485, a snake_case slug suitable as a json key,
|
||||
// and a boolean describing whether multiple copies can appear on an X509 cert.
|
||||
type OidDescription struct {
|
||||
Name string
|
||||
Short string
|
||||
Slug string
|
||||
Multiple bool
|
||||
}
|
||||
@@ -14,21 +15,29 @@ func describeOid(oid asn1.ObjectIdentifier) OidDescription {
|
||||
raw := oid.String()
|
||||
// Multiple should be true for any types that are []string in x509.pkix.Name. When in doubt, set it to true.
|
||||
names := map[string]OidDescription{
|
||||
"2.5.4.3": {"CommonName", "common_name", false},
|
||||
"2.5.4.5": {"EV Incorporation Registration Number", "ev_registration_number", false},
|
||||
"2.5.4.6": {"Country", "country", true},
|
||||
"2.5.4.7": {"Locality", "locality", true},
|
||||
"2.5.4.8": {"Province", "province", true},
|
||||
"2.5.4.10": {"Organization", "organization", true},
|
||||
"2.5.4.11": {"Organizational Unit", "organizational_unit", true},
|
||||
"2.5.4.15": {"Business Category", "business_category", true},
|
||||
"1.2.840.113549.1.9.1": {"Email Address", "email_address", true},
|
||||
"1.3.6.1.4.1.311.60.2.1.1": {"EV Incorporation Locality", "ev_locality", true},
|
||||
"1.3.6.1.4.1.311.60.2.1.2": {"EV Incorporation Province", "ev_province", true},
|
||||
"1.3.6.1.4.1.311.60.2.1.3": {"EV Incorporation Country", "ev_country", true},
|
||||
"2.5.4.3": {"CommonName", "CN", "common_name", false},
|
||||
"2.5.4.5": {"EV Incorporation Registration Number", "", "ev_registration_number", false},
|
||||
"2.5.4.6": {"Country", "C", "country", true},
|
||||
"2.5.4.7": {"Locality", "L", "locality", true},
|
||||
"2.5.4.8": {"Province", "ST", "province", true},
|
||||
"2.5.4.10": {"Organization", "O", "organization", true},
|
||||
"2.5.4.11": {"Organizational Unit", "OU", "organizational_unit", true},
|
||||
"2.5.4.15": {"Business Category", "", "business_category", true},
|
||||
"1.2.840.113549.1.9.1": {"Email Address", "", "email_address", true},
|
||||
"1.3.6.1.4.1.311.60.2.1.1": {"EV Incorporation Locality", "", "ev_locality", true},
|
||||
"1.3.6.1.4.1.311.60.2.1.2": {"EV Incorporation Province", "", "ev_province", true},
|
||||
"1.3.6.1.4.1.311.60.2.1.3": {"EV Incorporation Country", "", "ev_country", true},
|
||||
}
|
||||
if description, ok := names[raw]; ok {
|
||||
return description
|
||||
}
|
||||
return OidDescription{raw, raw, true}
|
||||
return OidDescription{raw, "", raw, true}
|
||||
}
|
||||
|
||||
func oidShort(oid asn1.ObjectIdentifier) string {
|
||||
return describeOid(oid).Short
|
||||
}
|
||||
|
||||
func oidName(oid asn1.ObjectIdentifier) string {
|
||||
return describeOid(oid).Name
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
app = kingpin.New("certigo", "A command line certificate examination utility.")
|
||||
app = kingpin.New("certigo", "A command line certificate examination utility.")
|
||||
verbose = app.Flag("verbose", "Print verbose").Short('v').Bool()
|
||||
|
||||
dump = app.Command("dump", "Display information about a certificate from a file/stdin.")
|
||||
dumpFiles = dump.Arg("file", "Certificate file to dump (or stdin if not specified).").ExistingFiles()
|
||||
@@ -91,7 +92,7 @@ func main() {
|
||||
} else {
|
||||
for i, cert := range result.Certificates {
|
||||
fmt.Fprintf(stdout, "** CERTIFICATE %d **\n", i+1)
|
||||
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert))
|
||||
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert, *verbose))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +130,7 @@ func main() {
|
||||
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeTLSToText(result.TLSConnectionState))
|
||||
for i, cert := range result.Certificates {
|
||||
fmt.Fprintf(stdout, "** CERTIFICATE %d **\n", i+1)
|
||||
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert))
|
||||
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert, *verbose))
|
||||
}
|
||||
printVerifyResult(stdout, *result.VerifyResult)
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ Set up test data.
|
||||
|
||||
Dump a live cert chain (squareup-chain.crt)
|
||||
|
||||
$ certigo dump squareup-chain.crt
|
||||
$ certigo --verbose dump squareup-chain.crt
|
||||
** CERTIFICATE 1 **
|
||||
Serial: 260680855742043049380997676879525498489
|
||||
Not Before: 2016-07-15 20:15:52 +0000 UTC
|
||||
|
||||
@@ -51,7 +51,7 @@ Set up test data.
|
||||
|
||||
Dump PEM blocks from a JCEKS keystore.
|
||||
|
||||
$ certigo dump --pem --password password example.jceks
|
||||
$ certigo --verbose dump --pem --password password example.jceks
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAyjhKEojYzEPP81BXEFvPS1sPlHk1yhsDQ0qRo8ovIwSmdZVj
|
||||
25zJq4yOg2fUXnrxx86gXSmbfvTRTxRM+3YwzEQciLiYUb84XxQX5WiHUnjZNvja
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
Set up test data.
|
||||
|
||||
$ cat > example-leaf.crt <<EOF
|
||||
> -----BEGIN CERTIFICATE-----
|
||||
> MIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV
|
||||
> BAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMH
|
||||
> ZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYxMDIyMTQxMVoX
|
||||
> DTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD
|
||||
> VQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxl
|
||||
> LWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7stSvfQyGuHw3
|
||||
> v34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKdsR/J5sbWSl8K/5djpzj31eIzqU69
|
||||
> w8v7SChM5x9bouDsABHz3kZucx5cSafEgJojysBkcrq3VY+aJanzbL+qErYX+lhR
|
||||
> pPcZK6JMWIwar8Y3B2la4yWwieecw2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84c
|
||||
> zKPyt9r40gDk2XiH/lGts5a94rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF
|
||||
> 5O5iSV9rEI+m2+7j2S+jHDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2
|
||||
> Np6i464lAgMBAAGjTzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAs
|
||||
> BgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJ
|
||||
> KoZIhvcNAQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sM
|
||||
> lM05kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7
|
||||
> LstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloSaa7d
|
||||
> vBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx8MNGvUeL
|
||||
> Fj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObiqdsJLMVvb2Xl
|
||||
> iJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIU=
|
||||
> -----END CERTIFICATE-----
|
||||
> EOF
|
||||
|
||||
Dump an example certificate (example-leaf.crt)
|
||||
|
||||
$ certigo dump example-leaf.crt
|
||||
** CERTIFICATE 1 **
|
||||
Not Before: 2016-06-10 22:14:11 +0000 UTC
|
||||
Not After : 2023-04-15 22:14:11 +0000 UTC
|
||||
Subject: C=US, ST=CA, O=certigo, OU=example, CN=example-leaf
|
||||
Issuer: C=US, ST=CA, O=certigo, OU=example, CN=example-leaf
|
||||
Alternate DNS Names:
|
||||
\tlocalhost (esc)
|
||||
Alternate IP Addresses:
|
||||
\t127.0.0.1 (esc)
|
||||
\t::1 (esc)
|
||||
|
||||
@@ -26,7 +26,7 @@ Set up test data.
|
||||
|
||||
Dump an example certificate (example-leaf.crt)
|
||||
|
||||
$ certigo dump example-leaf.crt
|
||||
$ certigo --verbose dump example-leaf.crt
|
||||
** CERTIFICATE 1 **
|
||||
Serial: 15384458167827828543
|
||||
Not Before: 2016-06-10 22:14:11 +0000 UTC
|
||||
|
||||
@@ -58,7 +58,7 @@ Set up test data.
|
||||
|
||||
Dump PEM blocks from a PKCS12 keystore.
|
||||
|
||||
$ certigo dump --pem --password password example.p12
|
||||
$ certigo --verbose dump --pem --password password example.p12
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDLDCCAhQCCQCa74bQsAj2/jANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJV
|
||||
UzELMAkGA1UECBMCQ0ExEDAOBgNVBAoTB2NlcnRpZ28xEDAOBgNVBAsTB2V4YW1w
|
||||
|
||||
@@ -19,7 +19,7 @@ Set up test data.
|
||||
|
||||
Dump an example certificate (example-leaf.crt)
|
||||
|
||||
$ certigo dump example-small-key.crt
|
||||
$ certigo --verbose dump example-small-key.crt
|
||||
** CERTIFICATE 1 **
|
||||
Serial: 14381893493177441266
|
||||
Not Before: 2016-06-10 22:14:12 +0000 UTC
|
||||
|
||||
Reference in New Issue
Block a user