From 1e2cdd799bdc92959e60e5bbe1c6b8d5098fba7d Mon Sep 17 00:00:00 2001 From: Christopher Denny Date: Wed, 1 Jun 2016 15:27:58 -0700 Subject: [PATCH 1/3] Added color output for start and expiry dates, documented methods. displayCert now prints out the start or expiry date in different colors depending on how close the deadline is. Also all methods have comments explaining arguments/return value and basic overview. --- display.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++--- main.go | 16 +++++++++--- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/display.go b/display.go index 19f42d2..2f62cb9 100644 --- a/display.go +++ b/display.go @@ -22,10 +22,17 @@ import ( "os" "strings" "text/template" + "time" + + "github.com/fatih/color" ) -var Layout = `Expiry Date: {{.NotAfter}} -Algorithm Type: {{.SignatureAlgorithm}} +/* + * Template used to display certificate to standard output. + */ +var Layout = `Enable Date: {{.NotBefore | enable}}`+ +`Expiry Date: {{.NotAfter | expire}}`+ +`Algorithm Type: {{.SignatureAlgorithm}} Subject Info: CommonName: {{.Subject.CommonName}} Organization: {{.Subject.Organization}} @@ -44,10 +51,18 @@ Alternate DNS Names: {{.DNSNames}} Serial Number: {{.SerialNumber}} ` +/* + * Arguments: Certificate to display + * Returns: N/A + * + * Function to display cert. + * Initializes template and template functions, then executes template. + */ func displayCert(cert *x509.Certificate) { - funcMap := template.FuncMap{ "hexify": hexify, + "enable": enable, + "expire": expire, } t := template.New("Cert template").Funcs(funcMap) t, _ = t.Parse(Layout) @@ -55,6 +70,59 @@ func displayCert(cert *x509.Certificate) { } +/* + * Arguments: Start date for certificate + * Returns: Empty string for the template + * + * Used to print in color the date cert becomes active. + * Prints date in green if cert enabled at least a day ago. + * Prints date in yellow if cert enabled within last day. + * Prints date in red if cert not yet valid. + */ +func enable(start time.Time) string { + now := time.Now() + day, _ := time.ParseDuration("24h") + threshold := start.Add(day) + if now.After(threshold) { + color.Green(start.String()) + } else if now.After(start) { + color.Yellow(start.String()) + } else { + color.Red(start.String()) + } + return "" +} + +/* + * Arguments: End date for certificate + * Returns: Empty string for the template + * + * Used to print in color the date the cert expires. + * Prints date in green if cert expires more than a month in the future. + * Prints date in yellow if cert expires within a month. + * Prints date in red if cert is expired. + */ +func expire(end time.Time) string { + now := time.Now() + month, _ := time.ParseDuration("720h") + threshold := now.Add(month) + if threshold.Before(end) { + color.Green(end.String()) + } else if now.Before(end) { + color.Yellow(end.String()) + } else { + color.Red(end.String()) + } + return "" +} + +/* + * Arguments: Byte array formatted key ID + * Returns: String version of key ID + * + * Converts Subject Key ID and Authority Key ID from + * byte arrays to a hex, colon separated format. + */ func hexify(arr []byte) string { hexed := "" for i := 0; i < len(arr); i++ { diff --git a/main.go b/main.go index 28b8b62..562cd12 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,9 @@ import ( "gopkg.in/alecthomas/kingpin.v2" ) +/* + * Variables used to setup command line interface. + */ var ( app = kingpin.New("certigo", "A command line certificate examination utility.") @@ -38,10 +41,8 @@ var ( ) func main() { - switch kingpin.MustParse(app.Parse(os.Args[1:])) { - //Dump Certificate - case dump.FullCommand(): + case dump.FullCommand(): //Dump certificate certs, err := getCerts(*dumpFile, *dumpType) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) @@ -53,6 +54,15 @@ func main() { } } +/* + * Arguments: file name and format + * Returns: Array of certificates contained in file + * + * Retrieves all certificates file given a format. + * If no foramt is specified, getCerts() guesses the format + * based on the file extension. + * If this doesn't work, it returns an error. + */ func getCerts(file, format string) ([]*x509.Certificate, error) { var certs []*x509.Certificate data, _ := ioutil.ReadFile(file) From 0a5be899705d6d375a810c3f275e101b37f082fd Mon Sep 17 00:00:00 2001 From: Christopher Denny Date: Wed, 1 Jun 2016 15:30:21 -0700 Subject: [PATCH 2/3] Display.go wasn't included in last commit. --- display.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/display.go b/display.go index 2f62cb9..c407510 100644 --- a/display.go +++ b/display.go @@ -30,9 +30,9 @@ import ( /* * Template used to display certificate to standard output. */ -var Layout = `Enable Date: {{.NotBefore | enable}}`+ -`Expiry Date: {{.NotAfter | expire}}`+ -`Algorithm Type: {{.SignatureAlgorithm}} +var Layout = `Enable Date: {{.NotBefore | enable}}` + + `Expiry Date: {{.NotAfter | expire}}` + + `Algorithm Type: {{.SignatureAlgorithm}} Subject Info: CommonName: {{.Subject.CommonName}} Organization: {{.Subject.Organization}} From abdfdc9ed13c6a3dc4d406d3f683ddc45d0225e9 Mon Sep 17 00:00:00 2001 From: Christopher Denny Date: Wed, 1 Jun 2016 16:25:01 -0700 Subject: [PATCH 3/3] Updated document style to match go design doc. Changed color display methods to return a string of the correct color, rather than printing it and returning an empty string. Changed names of color display methods to certStart and certEnd. --- display.go | 84 +++++++++++++++++++++--------------------------------- main.go | 17 ++++------- 2 files changed, 38 insertions(+), 63 deletions(-) diff --git a/display.go b/display.go index c407510..afb55d5 100644 --- a/display.go +++ b/display.go @@ -27,12 +27,9 @@ import ( "github.com/fatih/color" ) -/* - * Template used to display certificate to standard output. - */ -var Layout = `Enable Date: {{.NotBefore | enable}}` + - `Expiry Date: {{.NotAfter | expire}}` + - `Algorithm Type: {{.SignatureAlgorithm}} +var Layout = `Enable Date: {{.NotBefore | certStart}} +Expiry Date: {{.NotAfter | certEnd}} +Algorithm Type: {{.SignatureAlgorithm}} Subject Info: CommonName: {{.Subject.CommonName}} Organization: {{.Subject.Organization}} @@ -51,18 +48,14 @@ Alternate DNS Names: {{.DNSNames}} Serial Number: {{.SerialNumber}} ` -/* - * Arguments: Certificate to display - * Returns: N/A - * - * Function to display cert. - * Initializes template and template functions, then executes template. - */ +// displayCert takes in an x509 Certificate object 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 *x509.Certificate) { funcMap := template.FuncMap{ - "hexify": hexify, - "enable": enable, - "expire": expire, + "hexify": hexify, + "certStart": certStart, + "certEnd": certEnd, } t := template.New("Cert template").Funcs(funcMap) t, _ = t.Parse(Layout) @@ -70,59 +63,48 @@ func displayCert(cert *x509.Certificate) { } -/* - * Arguments: Start date for certificate - * Returns: Empty string for the template - * - * Used to print in color the date cert becomes active. - * Prints date in green if cert enabled at least a day ago. - * Prints date in yellow if cert enabled within last day. - * Prints date in red if cert not yet valid. - */ -func enable(start time.Time) string { +// certStart takes a given start time for the validity of +// a certificate and returns that time colored properly +// based on how close it is to expiry. If it's more than +// a day after the certificate became valid the string will +// be green. If it has been less than a day the string will +// be yellow. If the certificate is not yet valid, the string +// will be red. +func certStart(start time.Time) string { now := time.Now() day, _ := time.ParseDuration("24h") threshold := start.Add(day) if now.After(threshold) { - color.Green(start.String()) + return color.GreenString(start.String()) } else if now.After(start) { - color.Yellow(start.String()) + return color.YellowString(start.String()) } else { - color.Red(start.String()) + return color.RedString(start.String()) } - return "" } -/* - * Arguments: End date for certificate - * Returns: Empty string for the template - * - * Used to print in color the date the cert expires. - * Prints date in green if cert expires more than a month in the future. - * Prints date in yellow if cert expires within a month. - * Prints date in red if cert is expired. - */ -func expire(end time.Time) string { +// certEnd takes a given end time for the validity of +// a certificate and returns that time colored properly +// based on how close it is to expiry. If the certificate +// is more than a month away from expiring it returns a +// green string. If the certificate is less than a month +// from expiry it returns a yellow string. If the certificate +// is expired it returns a red string. +func certEnd(end time.Time) string { now := time.Now() month, _ := time.ParseDuration("720h") threshold := now.Add(month) if threshold.Before(end) { - color.Green(end.String()) + return color.GreenString(end.String()) } else if now.Before(end) { - color.Yellow(end.String()) + return color.YellowString(end.String()) } else { - color.Red(end.String()) + return color.RedString(end.String()) } - return "" } -/* - * Arguments: Byte array formatted key ID - * Returns: String version of key ID - * - * Converts Subject Key ID and Authority Key ID from - * byte arrays to a hex, colon separated format. - */ +// hexify returns a colon separated, hexadecimal representation +// of a given byte array. func hexify(arr []byte) string { hexed := "" for i := 0; i < len(arr); i++ { diff --git a/main.go b/main.go index 562cd12..6fd87d2 100644 --- a/main.go +++ b/main.go @@ -29,9 +29,6 @@ import ( "gopkg.in/alecthomas/kingpin.v2" ) -/* - * Variables used to setup command line interface. - */ var ( app = kingpin.New("certigo", "A command line certificate examination utility.") @@ -54,15 +51,11 @@ func main() { } } -/* - * Arguments: file name and format - * Returns: Array of certificates contained in file - * - * Retrieves all certificates file given a format. - * If no foramt is specified, getCerts() guesses the format - * based on the file extension. - * If this doesn't work, it returns an error. - */ +// getCerts takes in a filename and format type and returns an +// array of all the certificates found in that file. If no format +// is specified for the file, getCerts guesses what format was used +// based on the file extension used in the file name. If it can't +// guess based on this it returns and error. func getCerts(file, format string) ([]*x509.Certificate, error) { var certs []*x509.Certificate data, _ := ioutil.ReadFile(file)