Skip to content

Commit

Permalink
ADD: Add --depth flag to specify the depth of cert
Browse files Browse the repository at this point in the history
Added another flag --depth to connect and dump to limit the number
of certificates to be printed in --json or --pem flags to make is
easier to ignore if only the leaft certificate is required.

Old vs New Commands:
* dump just the leaf cert
old : certigo dump cert_chain.pem --json | jq '.certificates[0]'
new : certigo dump cert_chain.pem --json --depth 1 | jq
Similar with other flags eg --verbose or short
description

* connect to get just the leaf cert
old : certigo connect hostname --json | jq '.certificates[0]'
new : certigo connect hostname --json --depth 1 | jq

old : certigo connect hostname --json --start-tls ldap | jq
'.certificates[0]'
new : certigo connect hostname --json --start-tls ldap --depth 1 | jq

This option is not implemented in verify and can be added if there is a
good response to this commit.
  • Loading branch information
prateeknischal authored and Prateek Nischal committed Jan 23, 2020
1 parent 8071493 commit 92fe6ad
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Commands:
-p, --password=PASSWORD Password for PKCS12/JCEKS key stores (reads from TTY if missing).
-m, --pem Write output as PEM blocks instead of human-readable format.
-j, --json Write output as machine-readable JSON format.
-d, --depth=0 Certificate chain information upto a certain depth.
connect [<flags>] [<server:port>]
Connect to a server and print its certificate(s).
Expand All @@ -73,6 +74,7 @@ Commands:
--timeout=5s Timeout for connecting to remote server (can be '5m', '1s', etc).
-m, --pem Write output as PEM blocks instead of human-readable format.
-j, --json Write output as machine-readable JSON format.
-d, --depth=0 Certificate chain information upto a certain depth.
verify --name=NAME [<flags>] [<file>]
Verify a certificate chain from file/stdin against a name.
Expand Down
2 changes: 1 addition & 1 deletion lib/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Authority Key ID: {{.Issuer.KeyID | hexify}}
{{- if .BasicConstraints}}
Basic Constraints: CA:{{.BasicConstraints.IsCA}}{{if .BasicConstraints.MaxPathLen}}, pathlen:{{.BasicConstraints.MaxPathLen}}{{end}}{{end}}
{{- if .NameConstraints}}
Name Constraints{{if .NameConstraints.Critical}} (critical){{end}}:
Name Constraints{{if .NameConstraints.Critical}} (critical){{end}}:
{{- if .NameConstraints.PermittedDNSDomains}}
Permitted DNS domains:
{{wrapWith .Width "\n\t" (join ", " .NameConstraints.PermittedDNSDomains)}}
Expand Down
26 changes: 24 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var (
dumpPassword = dump.Flag("password", "Password for PKCS12/JCEKS key stores (reads from TTY if missing).").Short('p').String()
dumpPem = dump.Flag("pem", "Write output as PEM blocks instead of human-readable format.").Short('m').Bool()
dumpJSON = dump.Flag("json", "Write output as machine-readable JSON format.").Short('j').Bool()
dumpDepth = dump.Flag("depth", "Certificate chain information upto a certain depth.").Short('d').Default("0").Int()

connect = app.Command("connect", "Connect to a server and print its certificate(s).")
connectTo = connect.Arg("server[:port]", "Hostname or IP to connect to, with optional port.").String()
Expand All @@ -55,6 +56,7 @@ var (
connectPem = connect.Flag("pem", "Write output as PEM blocks instead of human-readable format.").Short('m').Bool()
connectJSON = connect.Flag("json", "Write output as machine-readable JSON format.").Short('j').Bool()
connectVerify = connect.Flag("verify", "Verify certificate chain.").Bool()
connectDepth = connect.Flag("depth", "Certificate chain information upto a certain depth.").Short('d').Default("0").Int()

verify = app.Command("verify", "Verify a certificate chain from file/stdin against a name.")
verifyFile = verify.Arg("file", "Certificate file to dump (or stdin if not specified).").ExistingFile()
Expand Down Expand Up @@ -104,11 +106,21 @@ func main() {
}
})

// Calculate the depth of certificate from the leaf up that needs to be processed
chainLength := len(result.Certificates)
idx := chainLength
if chainLength > *dumpDepth && *dumpDepth > 0 {
idx = *dumpDepth
}

if *dumpJSON {
// Adjust the length of the result.Certificates length
result.Certificates = result.Certificates[:idx]
blob, _ := json.Marshal(result)
fmt.Println(string(blob))
} else {
for i, cert := range result.Certificates {

for i, cert := range result.Certificates[:idx] {
fmt.Fprintf(stdout, "** CERTIFICATE %d **\n", i+1)
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert, terminalWidth, *verbose))
}
Expand All @@ -135,7 +147,14 @@ func main() {
}
result.TLSConnectionState = connState
result.CertificateRequestInfo = cri
for _, cert := range connState.PeerCertificates {

chainLength := len(connState.PeerCertificates)
idx := chainLength
if chainLength > *connectDepth && *connectDepth > 0 {
idx = *connectDepth
}

for _, cert := range connState.PeerCertificates[:idx] {
if *connectPem {
pem.Encode(os.Stdout, lib.EncodeX509ToPEM(cert, nil))
} else {
Expand All @@ -152,6 +171,9 @@ func main() {
verifyResult := lib.VerifyChain(connState.PeerCertificates, connState.OCSPResponse, hostname, *connectCaPath)
result.VerifyResult = &verifyResult

// Adjust the length of result.Certificates
result.Certificates = result.Certificates[:idx]

if *connectJSON {
blob, _ := json.Marshal(result)
fmt.Println(string(blob))
Expand Down

0 comments on commit 92fe6ad

Please sign in to comment.