From 8c399e4f1b2e4f790550b727aeafb8933055f329 Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Tue, 3 Jan 2017 21:38:18 -0800 Subject: [PATCH 1/7] Pull RDN printing into a seperate template with fixes Print all the values that Go parses out, and print OIDs and values for the ExtraNames Values that Go allows multiple values (everything other than CN) are printed multiple times instead of in a square-bracket array. Since most certs have only a single value for each, this just avoids the square brackets. --- lib/display.go | 54 +++++++++++++++++++++++++-------- tests/dump-cert-chain-to-text.t | 42 ++++++++++++++----------- tests/dump-leaf-to-text.t | 14 +++++---- tests/dump-small-key-to-text.t | 14 +++++---- 4 files changed, 81 insertions(+), 43 deletions(-) diff --git a/lib/display.go b/lib/display.go index e2b0451..6aa1686 100644 --- a/lib/display.go +++ b/lib/display.go @@ -29,23 +29,51 @@ import ( "github.com/fatih/color" ) -var layout = `{{if .Alias}}{{.Alias}} +var layout = ` +{{- define "PkixName" -}} +{{- if .CommonName}} + CommonName: {{.CommonName}} +{{- end -}} +{{- range .Organization}} + Organization: {{.}} +{{- end -}} +{{- range .OrganizationalUnit}} + OrganizationalUnit: {{.}} +{{- end -}} +{{- range .Country}} + Country: {{.}} +{{- end -}} +{{- range .Locality}} + Locality: {{.}} +{{- end -}} +{{- range .Province}} + Province: {{.}} +{{- end -}} +{{- range .StreetAddress}} + StreetAddress: {{.}} +{{- end -}} +{{- range .PostalCode}} + PostalCode: {{.}} +{{- end -}} +{{- range .ExtraNames -}} + {{- range $index, $type := .Type }} + {{- if $index }}.{{else}} + {{end -}} + {{- $type -}} + {{- end }}: {{ .Value }} +{{- end -}} +{{end -}} + +{{- if .Alias}}{{.Alias}} {{end}}Serial: {{.SerialNumber}} Not Before: {{.NotBefore | certStart}} Not After : {{.NotAfter | certEnd}} Signature : {{.SignatureAlgorithm | highlightAlgorithm}}{{if .IsSelfSigned}} (self-signed){{end}} -Subject Info:{{if .Subject.Name.CommonName}} - CommonName: {{.Subject.Name.CommonName}}{{end}}{{if .Subject.Name.Organization}} - Organization: {{.Subject.Name.Organization}}{{end}}{{if .Subject.Name.OrganizationalUnit}} - OrganizationalUnit: {{.Subject.Name.OrganizationalUnit}}{{end}}{{if .Subject.Name.Country}} - Country: {{.Subject.Name.Country}}{{end}}{{if .Subject.Name.Locality}} - Locality: {{.Subject.Name.Locality}}{{end}} -Issuer Info:{{if .Issuer.Name.CommonName}} - CommonName: {{.Issuer.Name.CommonName}}{{end}}{{if .Issuer.Name.Organization}} - Organization: {{.Issuer.Name.Organization}}{{end}}{{if .Issuer.Name.OrganizationalUnit}} - OrganizationalUnit: {{.Issuer.Name.OrganizationalUnit}}{{end}}{{if .Issuer.Name.Country}} - Country: {{.Issuer.Name.Country}}{{end}}{{if .Issuer.Name.Locality}} - Locality: {{.Issuer.Name.Locality}}{{end}}{{if .Subject.KeyID}} +Subject Info: + {{- template "PkixName" .Subject.Name}} +Issuer Info: + {{- template "PkixName" .Issuer.Name}} +{{- if .Subject.KeyID}} Subject Key ID : {{.Subject.KeyID | hexify}}{{end}}{{if .Issuer.KeyID}} Authority Key ID : {{.Issuer.KeyID | hexify}}{{end}}{{if .BasicConstraints}} Basic Constraints: CA:{{.BasicConstraints.IsCA}}{{if .BasicConstraints.MaxPathLen}}, pathlen:{{.BasicConstraints.MaxPathLen}}{{end}}{{end}}{{if .NameConstraints}} diff --git a/tests/dump-cert-chain-to-text.t b/tests/dump-cert-chain-to-text.t index 6544de1..2255a3a 100644 --- a/tests/dump-cert-chain-to-text.t +++ b/tests/dump-cert-chain-to-text.t @@ -115,14 +115,16 @@ Dump a live cert chain (squareup-chain.crt) Signature : SHA256-RSA Subject Info: \tCommonName: www.squareup.com (esc) - \tOrganization: [Square, Inc.] (esc) - \tCountry: [US] (esc) - \tLocality: [San Francisco] (esc) + \tOrganization: Square, Inc. (esc) + \tCountry: US (esc) + \tLocality: San Francisco (esc) + \tProvince: California (esc) Issuer Info: \tCommonName: Entrust Certification Authority - L1M (esc) - \tOrganization: [Entrust, Inc.] (esc) - \tOrganizationalUnit: [See www.entrust.net/legal-terms (c) 2014 Entrust, Inc. - for authorized use only] (esc) - \tCountry: [US] (esc) + \tOrganization: Entrust, Inc. (esc) + \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) + \tOrganizationalUnit: (c) 2014 Entrust, Inc. - for authorized use only (esc) + \tCountry: US (esc) Subject Key ID : D4:17:14:6F:0B:C5:20:A1:D6:FE:21:7E:DC:9E:F8:57:9C:ED:AE:6A Authority Key ID : C3:F7:D0:B5:2A:30:AD:AF:0D:91:21:70:39:54:DD:BC:89:70:C7:3A Basic Constraints: CA:false @@ -151,14 +153,16 @@ Dump a live cert chain (squareup-chain.crt) Signature : SHA256-RSA Subject Info: \tCommonName: Entrust Certification Authority - L1M (esc) - \tOrganization: [Entrust, Inc.] (esc) - \tOrganizationalUnit: [See www.entrust.net/legal-terms (c) 2014 Entrust, Inc. - for authorized use only] (esc) - \tCountry: [US] (esc) + \tOrganization: Entrust, Inc. (esc) + \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) + \tOrganizationalUnit: (c) 2014 Entrust, Inc. - for authorized use only (esc) + \tCountry: US (esc) Issuer Info: \tCommonName: Entrust Root Certification Authority - G2 (esc) - \tOrganization: [Entrust, Inc.] (esc) - \tOrganizationalUnit: [See www.entrust.net/legal-terms (c) 2009 Entrust, Inc. - for authorized use only] (esc) - \tCountry: [US] (esc) + \tOrganization: Entrust, Inc. (esc) + \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) + \tOrganizationalUnit: (c) 2009 Entrust, Inc. - for authorized use only (esc) + \tCountry: US (esc) Subject Key ID : C3:F7:D0:B5:2A:30:AD:AF:0D:91:21:70:39:54:DD:BC:89:70:C7:3A Authority Key ID : 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB Basic Constraints: CA:true, pathlen:0 @@ -176,14 +180,16 @@ Dump a live cert chain (squareup-chain.crt) Signature : SHA256-RSA Subject Info: \tCommonName: Entrust Root Certification Authority - G2 (esc) - \tOrganization: [Entrust, Inc.] (esc) - \tOrganizationalUnit: [See www.entrust.net/legal-terms (c) 2009 Entrust, Inc. - for authorized use only] (esc) - \tCountry: [US] (esc) + \tOrganization: Entrust, Inc. (esc) + \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) + \tOrganizationalUnit: (c) 2009 Entrust, Inc. - for authorized use only (esc) + \tCountry: US (esc) Issuer Info: \tCommonName: Entrust Root Certification Authority (esc) - \tOrganization: [Entrust, Inc.] (esc) - \tOrganizationalUnit: [www.entrust.net/CPS is incorporated by reference (c) 2006 Entrust, Inc.] (esc) - \tCountry: [US] (esc) + \tOrganization: Entrust, Inc. (esc) + \tOrganizationalUnit: www.entrust.net/CPS is incorporated by reference (esc) + \tOrganizationalUnit: (c) 2006 Entrust, Inc. (esc) + \tCountry: US (esc) Subject Key ID : 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB Authority Key ID : 68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D Basic Constraints: CA:true, pathlen:1 diff --git a/tests/dump-leaf-to-text.t b/tests/dump-leaf-to-text.t index 719b819..d72ca93 100644 --- a/tests/dump-leaf-to-text.t +++ b/tests/dump-leaf-to-text.t @@ -34,14 +34,16 @@ Dump an example certificate (example-leaf.crt) Signature : SHA256-RSA Subject Info: \tCommonName: example-leaf (esc) - \tOrganization: [certigo] (esc) - \tOrganizationalUnit: [example] (esc) - \tCountry: [US] (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCountry: US (esc) + \tProvince: CA (esc) Issuer Info: \tCommonName: example-leaf (esc) - \tOrganization: [certigo] (esc) - \tOrganizationalUnit: [example] (esc) - \tCountry: [US] (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCountry: US (esc) + \tProvince: CA (esc) Extended Key Usage: \tClient Auth (esc) \tServer Auth (esc) diff --git a/tests/dump-small-key-to-text.t b/tests/dump-small-key-to-text.t index b0c9016..0ae7290 100644 --- a/tests/dump-small-key-to-text.t +++ b/tests/dump-small-key-to-text.t @@ -27,14 +27,16 @@ Dump an example certificate (example-leaf.crt) Signature : SHA256-RSA (self-signed) Subject Info: \tCommonName: example-small-key (esc) - \tOrganization: [certigo] (esc) - \tOrganizationalUnit: [example] (esc) - \tCountry: [US] (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCountry: US (esc) + \tProvince: CA (esc) Issuer Info: \tCommonName: example-small-key (esc) - \tOrganization: [certigo] (esc) - \tOrganizationalUnit: [example] (esc) - \tCountry: [US] (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCountry: US (esc) + \tProvince: CA (esc) Warnings: \tCertificate is not in X509v3 format (version is 2) (esc) \tSize of RSA key should be at least 2048 bits (esc) From 65402b26f57004a2386892f0e6a209f040c6637f Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Wed, 4 Jan 2017 15:39:24 -0800 Subject: [PATCH 2/7] Make a test cert with a custom OID in the DN --- test-certs/Makefile | 10 +++++++++- test-certs/example-custom-oid.conf | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test-certs/example-custom-oid.conf diff --git a/test-certs/Makefile b/test-certs/Makefile index ce9eee4..854235e 100644 --- a/test-certs/Makefile +++ b/test-certs/Makefile @@ -1,6 +1,7 @@ TARGETS = \ example-root example-leaf example-sha1 example-md5 example-root-bad-ku \ - example-bad-serial example-small-key example-expired example-elliptic-sha1 + example-bad-serial example-small-key example-expired example-elliptic-sha1 \ + example-custom-oid all: \ $(addsuffix .crt,$(TARGETS)) \ @@ -72,3 +73,10 @@ example-elliptic-sha1.key: example-elliptic-sha1.crt: example-elliptic-sha1.csr openssl x509 -req -in $< -signkey $(@:.crt=.key) -out $@ -days 2500 -extfile openssl.ext -extensions leaf + +# Custom OID +example-custom-oid.csr: example-custom-oid.key + openssl req -new -config example-custom-oid.conf -key $< -out $@ + +example-custom-oid.crt: example-custom-oid.csr + openssl x509 -req -sha256 -in $< -signkey $(@:.crt=.key) -out $@ -days 2500 -extfile openssl.ext -extensions leaf diff --git a/test-certs/example-custom-oid.conf b/test-certs/example-custom-oid.conf new file mode 100644 index 0000000..1126f55 --- /dev/null +++ b/test-certs/example-custom-oid.conf @@ -0,0 +1,12 @@ +oid_section = OIDs + +[ req ] +distinguished_name = dn +prompt = no + +[ OIDs ] +CustomTestOID=1.3.6.1.4.1.36914 + +[ dn ] +CN = example-custom-oids +CustomTestOID = example From fd470514d7afb66496df3bf5b4882f6d44fdf618 Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Wed, 4 Jan 2017 16:45:12 -0800 Subject: [PATCH 3/7] Simplify subject printing Note that RDNs now appear in the order they're in the pkix.Name, instead of a fixed order --- lib/display.go | 53 ++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/lib/display.go b/lib/display.go index 6aa1686..d52a9df 100644 --- a/lib/display.go +++ b/lib/display.go @@ -26,41 +26,15 @@ import ( "text/template" "time" + "encoding/asn1" + "github.com/fatih/color" ) var layout = ` {{- define "PkixName" -}} -{{- if .CommonName}} - CommonName: {{.CommonName}} -{{- end -}} -{{- range .Organization}} - Organization: {{.}} -{{- end -}} -{{- range .OrganizationalUnit}} - OrganizationalUnit: {{.}} -{{- end -}} -{{- range .Country}} - Country: {{.}} -{{- end -}} -{{- range .Locality}} - Locality: {{.}} -{{- end -}} -{{- range .Province}} - Province: {{.}} -{{- end -}} -{{- range .StreetAddress}} - StreetAddress: {{.}} -{{- end -}} -{{- range .PostalCode}} - PostalCode: {{.}} -{{- end -}} -{{- range .ExtraNames -}} - {{- range $index, $type := .Type }} - {{- if $index }}.{{else}} - {{end -}} - {{- $type -}} - {{- end }}: {{ .Value }} +{{- range .Names}} + {{ .Type | oidify }}: {{ .Value }} {{- end -}} {{end -}} @@ -153,6 +127,7 @@ func displayCert(cert simpleCertificate) []byte { "hexify": hexify, "keyUsage": keyUsage, "extKeyUsage": extKeyUsage, + "oidify": oidify, } t := template.New("Cert template").Funcs(funcMap) t, err := t.Parse(layout) @@ -246,3 +221,21 @@ func certEnd(end time.Time) string { func redify(text string) string { return red.SprintfFunc()("%s", text) } + +func oidify(oid asn1.ObjectIdentifier) string { + raw := oid.String() + names := map[string]string{ + "2.5.4.3": "CommonName", + "2.5.4.6": "Country", + "2.5.4.7": "Locality", + "2.5.4.8": "Province", + "2.5.4.10": "Organization", + "2.5.4.11": "OrganizationalUnit", + "1.2.840.113549.1.9.1": "emailAddress", + } + name, ok := names[raw] + if ok { + return name + } + return raw +} From b1898291fa4280a985979289ecfd2910fef7ddab Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Wed, 4 Jan 2017 17:27:23 -0800 Subject: [PATCH 4/7] Add more Subject fields, especially for EV certs --- lib/display.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/display.go b/lib/display.go index d52a9df..d4820b9 100644 --- a/lib/display.go +++ b/lib/display.go @@ -225,13 +225,18 @@ func redify(text string) string { func oidify(oid asn1.ObjectIdentifier) string { raw := oid.String() names := map[string]string{ - "2.5.4.3": "CommonName", - "2.5.4.6": "Country", - "2.5.4.7": "Locality", - "2.5.4.8": "Province", - "2.5.4.10": "Organization", - "2.5.4.11": "OrganizationalUnit", - "1.2.840.113549.1.9.1": "emailAddress", + "2.5.4.3": "CommonName", + "2.5.4.5": "Serial Number", + "2.5.4.6": "Country", + "2.5.4.7": "Locality", + "2.5.4.8": "Province", + "2.5.4.10": "Organization", + "2.5.4.11": "OrganizationalUnit", + "2.5.4.15": "Business Category", + "1.2.840.113549.1.9.1": "emailAddress", + "1.3.6.1.4.1.311.60.2.1.1": "EV Locality", + "1.3.6.1.4.1.311.60.2.1.2": "EV Province", + "1.3.6.1.4.1.311.60.2.1.3": "EV Country", } name, ok := names[raw] if ok { From 8274156251ab4f6a254ecda154e8a2a7fca2fd5a Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Wed, 4 Jan 2017 17:31:30 -0800 Subject: [PATCH 5/7] Update tests with additional subject fields There's some reordering going too --- tests/dump-cert-chain-to-text.t | 30 +++++++++++++++++------------- tests/dump-leaf-to-text.t | 12 ++++++------ tests/dump-small-key-to-text.t | 12 ++++++------ 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/tests/dump-cert-chain-to-text.t b/tests/dump-cert-chain-to-text.t index 2255a3a..e4c71df 100644 --- a/tests/dump-cert-chain-to-text.t +++ b/tests/dump-cert-chain-to-text.t @@ -114,17 +114,21 @@ Dump a live cert chain (squareup-chain.crt) Not After : 2017-07-31 20:45:50 +0000 UTC Signature : SHA256-RSA Subject Info: - \tCommonName: www.squareup.com (esc) - \tOrganization: Square, Inc. (esc) \tCountry: US (esc) - \tLocality: San Francisco (esc) \tProvince: California (esc) + \tLocality: San Francisco (esc) + \tEV Country: US (esc) + \tEV Province: Delaware (esc) + \tOrganization: Square, Inc. (esc) + \tBusiness Category: Private Organization (esc) + \tSerial Number: 4699855 (esc) + \tCommonName: www.squareup.com (esc) Issuer Info: - \tCommonName: Entrust Certification Authority - L1M (esc) + \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) \tOrganizationalUnit: (c) 2014 Entrust, Inc. - for authorized use only (esc) - \tCountry: US (esc) + \tCommonName: Entrust Certification Authority - L1M (esc) Subject Key ID : D4:17:14:6F:0B:C5:20:A1:D6:FE:21:7E:DC:9E:F8:57:9C:ED:AE:6A Authority Key ID : C3:F7:D0:B5:2A:30:AD:AF:0D:91:21:70:39:54:DD:BC:89:70:C7:3A Basic Constraints: CA:false @@ -152,17 +156,17 @@ Dump a live cert chain (squareup-chain.crt) Not After : 2030-10-15 15:55:03 +0000 UTC Signature : SHA256-RSA Subject Info: - \tCommonName: Entrust Certification Authority - L1M (esc) + \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) \tOrganizationalUnit: (c) 2014 Entrust, Inc. - for authorized use only (esc) - \tCountry: US (esc) + \tCommonName: Entrust Certification Authority - L1M (esc) Issuer Info: - \tCommonName: Entrust Root Certification Authority - G2 (esc) + \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) \tOrganizationalUnit: (c) 2009 Entrust, Inc. - for authorized use only (esc) - \tCountry: US (esc) + \tCommonName: Entrust Root Certification Authority - G2 (esc) Subject Key ID : C3:F7:D0:B5:2A:30:AD:AF:0D:91:21:70:39:54:DD:BC:89:70:C7:3A Authority Key ID : 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB Basic Constraints: CA:true, pathlen:0 @@ -179,17 +183,17 @@ Dump a live cert chain (squareup-chain.crt) Not After : 2024-09-23 01:31:53 +0000 UTC Signature : SHA256-RSA Subject Info: - \tCommonName: Entrust Root Certification Authority - G2 (esc) + \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) \tOrganizationalUnit: (c) 2009 Entrust, Inc. - for authorized use only (esc) - \tCountry: US (esc) + \tCommonName: Entrust Root Certification Authority - G2 (esc) Issuer Info: - \tCommonName: Entrust Root Certification Authority (esc) + \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) \tOrganizationalUnit: www.entrust.net/CPS is incorporated by reference (esc) \tOrganizationalUnit: (c) 2006 Entrust, Inc. (esc) - \tCountry: US (esc) + \tCommonName: Entrust Root Certification Authority (esc) Subject Key ID : 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB Authority Key ID : 68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D Basic Constraints: CA:true, pathlen:1 diff --git a/tests/dump-leaf-to-text.t b/tests/dump-leaf-to-text.t index d72ca93..d2abcc7 100644 --- a/tests/dump-leaf-to-text.t +++ b/tests/dump-leaf-to-text.t @@ -33,17 +33,17 @@ Dump an example certificate (example-leaf.crt) Not After : 2023-04-15 22:14:11 +0000 UTC Signature : SHA256-RSA Subject Info: - \tCommonName: example-leaf (esc) - \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) \tCountry: US (esc) \tProvince: CA (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCommonName: example-leaf (esc) Issuer Info: - \tCommonName: example-leaf (esc) - \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) \tCountry: US (esc) \tProvince: CA (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCommonName: example-leaf (esc) Extended Key Usage: \tClient Auth (esc) \tServer Auth (esc) diff --git a/tests/dump-small-key-to-text.t b/tests/dump-small-key-to-text.t index 0ae7290..797eef8 100644 --- a/tests/dump-small-key-to-text.t +++ b/tests/dump-small-key-to-text.t @@ -26,17 +26,17 @@ Dump an example certificate (example-leaf.crt) Not After : 2023-04-15 22:14:12 +0000 UTC Signature : SHA256-RSA (self-signed) Subject Info: - \tCommonName: example-small-key (esc) - \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) \tCountry: US (esc) \tProvince: CA (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCommonName: example-small-key (esc) Issuer Info: - \tCommonName: example-small-key (esc) - \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) \tCountry: US (esc) \tProvince: CA (esc) + \tOrganization: certigo (esc) + \tOrganizationalUnit: example (esc) + \tCommonName: example-small-key (esc) Warnings: \tCertificate is not in X509v3 format (version is 2) (esc) \tSize of RSA key should be at least 2048 bits (esc) From 1ff7c9b20c44c0477a4b2b5b1b348b2c4fcaec60 Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Tue, 14 Feb 2017 21:07:17 -0800 Subject: [PATCH 6/7] Update OID display per review feedback --- lib/display.go | 10 +++++----- tests/dump-cert-chain-to-text.t | 26 +++++++++++++------------- tests/dump-leaf-to-text.t | 4 ++-- tests/dump-small-key-to-text.t | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/display.go b/lib/display.go index d4820b9..1c98d53 100644 --- a/lib/display.go +++ b/lib/display.go @@ -226,17 +226,17 @@ func oidify(oid asn1.ObjectIdentifier) string { raw := oid.String() names := map[string]string{ "2.5.4.3": "CommonName", - "2.5.4.5": "Serial Number", + "2.5.4.5": "EV Incorporation Registration Number", "2.5.4.6": "Country", "2.5.4.7": "Locality", "2.5.4.8": "Province", "2.5.4.10": "Organization", - "2.5.4.11": "OrganizationalUnit", + "2.5.4.11": "Organizational Unit", "2.5.4.15": "Business Category", "1.2.840.113549.1.9.1": "emailAddress", - "1.3.6.1.4.1.311.60.2.1.1": "EV Locality", - "1.3.6.1.4.1.311.60.2.1.2": "EV Province", - "1.3.6.1.4.1.311.60.2.1.3": "EV Country", + "1.3.6.1.4.1.311.60.2.1.1": "EV Incorporation Locality", + "1.3.6.1.4.1.311.60.2.1.2": "EV Incorporation Province", + "1.3.6.1.4.1.311.60.2.1.3": "EV Incorporation Country", } name, ok := names[raw] if ok { diff --git a/tests/dump-cert-chain-to-text.t b/tests/dump-cert-chain-to-text.t index e4c71df..d2704ef 100644 --- a/tests/dump-cert-chain-to-text.t +++ b/tests/dump-cert-chain-to-text.t @@ -117,17 +117,17 @@ Dump a live cert chain (squareup-chain.crt) \tCountry: US (esc) \tProvince: California (esc) \tLocality: San Francisco (esc) - \tEV Country: US (esc) - \tEV Province: Delaware (esc) + \tEV Incorporation Country: US (esc) + \tEV Incorporation Province: Delaware (esc) \tOrganization: Square, Inc. (esc) \tBusiness Category: Private Organization (esc) - \tSerial Number: 4699855 (esc) + \tEV Incorporation Registration Number: 4699855 (esc) \tCommonName: www.squareup.com (esc) Issuer Info: \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) - \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) - \tOrganizationalUnit: (c) 2014 Entrust, Inc. - for authorized use only (esc) + \tOrganizational Unit: See www.entrust.net/legal-terms (esc) + \tOrganizational Unit: (c) 2014 Entrust, Inc. - for authorized use only (esc) \tCommonName: Entrust Certification Authority - L1M (esc) Subject Key ID : D4:17:14:6F:0B:C5:20:A1:D6:FE:21:7E:DC:9E:F8:57:9C:ED:AE:6A Authority Key ID : C3:F7:D0:B5:2A:30:AD:AF:0D:91:21:70:39:54:DD:BC:89:70:C7:3A @@ -158,14 +158,14 @@ Dump a live cert chain (squareup-chain.crt) Subject Info: \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) - \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) - \tOrganizationalUnit: (c) 2014 Entrust, Inc. - for authorized use only (esc) + \tOrganizational Unit: See www.entrust.net/legal-terms (esc) + \tOrganizational Unit: (c) 2014 Entrust, Inc. - for authorized use only (esc) \tCommonName: Entrust Certification Authority - L1M (esc) Issuer Info: \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) - \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) - \tOrganizationalUnit: (c) 2009 Entrust, Inc. - for authorized use only (esc) + \tOrganizational Unit: See www.entrust.net/legal-terms (esc) + \tOrganizational Unit: (c) 2009 Entrust, Inc. - for authorized use only (esc) \tCommonName: Entrust Root Certification Authority - G2 (esc) Subject Key ID : C3:F7:D0:B5:2A:30:AD:AF:0D:91:21:70:39:54:DD:BC:89:70:C7:3A Authority Key ID : 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB @@ -185,14 +185,14 @@ Dump a live cert chain (squareup-chain.crt) Subject Info: \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) - \tOrganizationalUnit: See www.entrust.net/legal-terms (esc) - \tOrganizationalUnit: (c) 2009 Entrust, Inc. - for authorized use only (esc) + \tOrganizational Unit: See www.entrust.net/legal-terms (esc) + \tOrganizational Unit: (c) 2009 Entrust, Inc. - for authorized use only (esc) \tCommonName: Entrust Root Certification Authority - G2 (esc) Issuer Info: \tCountry: US (esc) \tOrganization: Entrust, Inc. (esc) - \tOrganizationalUnit: www.entrust.net/CPS is incorporated by reference (esc) - \tOrganizationalUnit: (c) 2006 Entrust, Inc. (esc) + \tOrganizational Unit: www.entrust.net/CPS is incorporated by reference (esc) + \tOrganizational Unit: (c) 2006 Entrust, Inc. (esc) \tCommonName: Entrust Root Certification Authority (esc) Subject Key ID : 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB Authority Key ID : 68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D diff --git a/tests/dump-leaf-to-text.t b/tests/dump-leaf-to-text.t index d2abcc7..602b216 100644 --- a/tests/dump-leaf-to-text.t +++ b/tests/dump-leaf-to-text.t @@ -36,13 +36,13 @@ Dump an example certificate (example-leaf.crt) \tCountry: US (esc) \tProvince: CA (esc) \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) + \tOrganizational Unit: example (esc) \tCommonName: example-leaf (esc) Issuer Info: \tCountry: US (esc) \tProvince: CA (esc) \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) + \tOrganizational Unit: example (esc) \tCommonName: example-leaf (esc) Extended Key Usage: \tClient Auth (esc) diff --git a/tests/dump-small-key-to-text.t b/tests/dump-small-key-to-text.t index 797eef8..35b30f3 100644 --- a/tests/dump-small-key-to-text.t +++ b/tests/dump-small-key-to-text.t @@ -29,13 +29,13 @@ Dump an example certificate (example-leaf.crt) \tCountry: US (esc) \tProvince: CA (esc) \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) + \tOrganizational Unit: example (esc) \tCommonName: example-small-key (esc) Issuer Info: \tCountry: US (esc) \tProvince: CA (esc) \tOrganization: certigo (esc) - \tOrganizationalUnit: example (esc) + \tOrganizational Unit: example (esc) \tCommonName: example-small-key (esc) Warnings: \tCertificate is not in X509v3 format (version is 2) (esc) From aee9f5e4e84e26ec718b56f90edcd1e8ad042eca Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Tue, 14 Feb 2017 21:40:46 -0800 Subject: [PATCH 7/7] Print full subject in JSON (instead of hardcoded list of members) --- lib/display.go | 21 +-------------------- lib/encoder.go | 25 +++++++++++-------------- lib/oids.go | 34 ++++++++++++++++++++++++++++++++++ tests/dump-leaf-to-json.t | 2 +- tests/dump-small-key-to-json.t | 2 +- 5 files changed, 48 insertions(+), 36 deletions(-) create mode 100644 lib/oids.go diff --git a/lib/display.go b/lib/display.go index 1c98d53..d011cb9 100644 --- a/lib/display.go +++ b/lib/display.go @@ -223,24 +223,5 @@ func redify(text string) string { } func oidify(oid asn1.ObjectIdentifier) string { - raw := oid.String() - names := map[string]string{ - "2.5.4.3": "CommonName", - "2.5.4.5": "EV Incorporation Registration Number", - "2.5.4.6": "Country", - "2.5.4.7": "Locality", - "2.5.4.8": "Province", - "2.5.4.10": "Organization", - "2.5.4.11": "Organizational Unit", - "2.5.4.15": "Business Category", - "1.2.840.113549.1.9.1": "emailAddress", - "1.3.6.1.4.1.311.60.2.1.1": "EV Incorporation Locality", - "1.3.6.1.4.1.311.60.2.1.2": "EV Incorporation Province", - "1.3.6.1.4.1.311.60.2.1.3": "EV Incorporation Country", - } - name, ok := names[raw] - if ok { - return name - } - return raw + return describeOid(oid).Name } diff --git a/lib/encoder.go b/lib/encoder.go index 75921ba..c1e9bad 100644 --- a/lib/encoder.go +++ b/lib/encoder.go @@ -180,21 +180,18 @@ func createSimpleCertificate(name string, cert *x509.Certificate) simpleCertific func (p simplePKIXName) MarshalJSON() ([]byte, error) { out := map[string]interface{}{} - if p.Name.CommonName != "" { - out["common_name"] = p.Name.CommonName - } - if len(p.Name.Organization) > 0 { - out["organization"] = p.Name.Organization - } - if len(p.Name.OrganizationalUnit) > 0 { - out["organizational_unit"] = p.Name.OrganizationalUnit - } - if len(p.Name.Country) > 0 { - out["country"] = p.Name.Country - } - if len(p.Name.Locality) > 0 { - out["locality"] = p.Name.Locality + for _, rdn := range p.Name.Names { + oid := describeOid(rdn.Type) + if prev, ok := out[oid.Slug]; oid.Multiple && ok { + l := prev.([]interface{}) + out[oid.Slug] = append(l, rdn.Value) + } else if oid.Multiple { + out[oid.Slug] = []interface{}{rdn.Value} + } else { + out[oid.Slug] = rdn.Value + } } + if len(p.KeyID) > 0 { out["key_id"] = hexify(p.KeyID) } diff --git a/lib/oids.go b/lib/oids.go new file mode 100644 index 0000000..1e3d1f3 --- /dev/null +++ b/lib/oids.go @@ -0,0 +1,34 @@ +package lib + +import "encoding/asn1" + +// OidDescription returns a human-readable name, 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 + Slug string + Multiple bool +} + +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}, + } + if description, ok := names[raw]; ok { + return description + } + return OidDescription{raw, raw, true} +} diff --git a/tests/dump-leaf-to-json.t b/tests/dump-leaf-to-json.t index 3a9d1cc..b4eeadb 100644 --- a/tests/dump-leaf-to-json.t +++ b/tests/dump-leaf-to-json.t @@ -27,4 +27,4 @@ Set up test data. Dump an example certificate (example-leaf.crt) to JSON output $ certigo dump --json example-leaf.crt - {"certificates":[{"serial":"15384458167827828543","not_before":"2016-06-10T22:14:11Z","not_after":"2023-04-15T22:14:11Z","signature_algorithm":"SHA256-RSA","is_self_signed":false,"subject":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"]},"issuer":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"]},"extended_key_usage":["Client Auth","Server Auth"],"dns_names":["localhost"],"ip_addresses":["127.0.0.1","::1"],"pem":"-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV\nBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMH\nZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYxMDIyMTQxMVoX\nDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxl\nLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7stSvfQyGuHw3\nv34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKdsR/J5sbWSl8K/5djpzj31eIzqU69\nw8v7SChM5x9bouDsABHz3kZucx5cSafEgJojysBkcrq3VY+aJanzbL+qErYX+lhR\npPcZK6JMWIwar8Y3B2la4yWwieecw2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84c\nzKPyt9r40gDk2XiH/lGts5a94rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF\n5O5iSV9rEI+m2+7j2S+jHDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2\nNp6i464lAgMBAAGjTzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAs\nBgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJ\nKoZIhvcNAQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sM\nlM05kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7\nLstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloSaa7d\nvBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx8MNGvUeL\nFj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObiqdsJLMVvb2Xl\niJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIU=\n-----END CERTIFICATE-----\n"}]} + {"certificates":[{"serial":"15384458167827828543","not_before":"2016-06-10T22:14:11Z","not_after":"2023-04-15T22:14:11Z","signature_algorithm":"SHA256-RSA","is_self_signed":false,"subject":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"issuer":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"extended_key_usage":["Client Auth","Server Auth"],"dns_names":["localhost"],"ip_addresses":["127.0.0.1","::1"],"pem":"-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV\nBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMH\nZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYxMDIyMTQxMVoX\nDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxl\nLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7stSvfQyGuHw3\nv34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKdsR/J5sbWSl8K/5djpzj31eIzqU69\nw8v7SChM5x9bouDsABHz3kZucx5cSafEgJojysBkcrq3VY+aJanzbL+qErYX+lhR\npPcZK6JMWIwar8Y3B2la4yWwieecw2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84c\nzKPyt9r40gDk2XiH/lGts5a94rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF\n5O5iSV9rEI+m2+7j2S+jHDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2\nNp6i464lAgMBAAGjTzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAs\nBgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJ\nKoZIhvcNAQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sM\nlM05kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7\nLstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloSaa7d\nvBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx8MNGvUeL\nFj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObiqdsJLMVvb2Xl\niJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIU=\n-----END CERTIFICATE-----\n"}]} diff --git a/tests/dump-small-key-to-json.t b/tests/dump-small-key-to-json.t index 2870269..3b17a16 100644 --- a/tests/dump-small-key-to-json.t +++ b/tests/dump-small-key-to-json.t @@ -20,4 +20,4 @@ Set up test data. Dump an example certificate (example-leaf.crt) to JSON output $ certigo dump --json example-small-key.crt - {"certificates":[{"serial":"14381893493177441266","not_before":"2016-06-10T22:14:12Z","not_after":"2023-04-15T22:14:12Z","signature_algorithm":"SHA256-RSA","is_self_signed":true,"subject":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"]},"issuer":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"]},"warnings":["Certificate is not in X509v3 format (version is 2)","Size of RSA key should be at least 2048 bits"],"pem":"-----BEGIN CERTIFICATE-----\nMIICKzCCAZQCCQDHlr/u+lfb8jANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExEDAOBgNVBAoTB2NlcnRpZ28xEDAOBgNVBAsTB2V4YW1w\nbGUxGjAYBgNVBAMTEWV4YW1wbGUtc21hbGwta2V5MB4XDTE2MDYxMDIyMTQxMloX\nDTIzMDQxNTIyMTQxMlowWjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRowGAYDVQQDExFleGFtcGxl\nLXNtYWxsLWtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAlzyCIeP1T87k\n1rHVMtbaGXIWpK/VQuvuXwig+e3ct1ajA4bw0BAInXZ37FEGGSCUix0k/CjH2Nlt\nGREtwbahE0k5oTkVbA5XS4xkNs0M0poAFN5OiFKEAqZ014hqhvKnEUQ2oTe9SVOR\nWw49mLNg36AIEE2Fu2KQb/VT90cwwD0CAwEAATANBgkqhkiG9w0BAQsFAAOBgQBV\nsJ4Vb2L1ywLVeAxNqY0PZqS7a8Q2GLhNr5V+3hOoWn7bwqQ7L06UJGSrcLOPZeIH\nIWM20aOFHSTWbocd4f+m6s3llyXwBBlK2BPZbWv0OeAHgjN9AVav4flAZ4oD2GxA\naJkGAXmR9QzZNJLai5mv3L/B/p/NxeU3UGfaySxVvw==\n-----END CERTIFICATE-----\n"}]} + {"certificates":[{"serial":"14381893493177441266","not_before":"2016-06-10T22:14:12Z","not_after":"2023-04-15T22:14:12Z","signature_algorithm":"SHA256-RSA","is_self_signed":true,"subject":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"issuer":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"warnings":["Certificate is not in X509v3 format (version is 2)","Size of RSA key should be at least 2048 bits"],"pem":"-----BEGIN CERTIFICATE-----\nMIICKzCCAZQCCQDHlr/u+lfb8jANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExEDAOBgNVBAoTB2NlcnRpZ28xEDAOBgNVBAsTB2V4YW1w\nbGUxGjAYBgNVBAMTEWV4YW1wbGUtc21hbGwta2V5MB4XDTE2MDYxMDIyMTQxMloX\nDTIzMDQxNTIyMTQxMlowWjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRowGAYDVQQDExFleGFtcGxl\nLXNtYWxsLWtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAlzyCIeP1T87k\n1rHVMtbaGXIWpK/VQuvuXwig+e3ct1ajA4bw0BAInXZ37FEGGSCUix0k/CjH2Nlt\nGREtwbahE0k5oTkVbA5XS4xkNs0M0poAFN5OiFKEAqZ014hqhvKnEUQ2oTe9SVOR\nWw49mLNg36AIEE2Fu2KQb/VT90cwwD0CAwEAATANBgkqhkiG9w0BAQsFAAOBgQBV\nsJ4Vb2L1ywLVeAxNqY0PZqS7a8Q2GLhNr5V+3hOoWn7bwqQ7L06UJGSrcLOPZeIH\nIWM20aOFHSTWbocd4f+m6s3llyXwBBlK2BPZbWv0OeAHgjN9AVav4flAZ4oD2GxA\naJkGAXmR9QzZNJLai5mv3L/B/p/NxeU3UGfaySxVvw==\n-----END CERTIFICATE-----\n"}]}