Skip to content

Commit

Permalink
print input format guessed by certigo (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
captiosus committed Feb 25, 2020
1 parent 23ed60d commit f81df5c
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 22 deletions.
9 changes: 6 additions & 3 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,17 @@ func Run(args []string, tty terminal.Terminal) int {
}()

if *dumpPem {
err = lib.ReadAsPEMFromFiles(files, *dumpType, tty.ReadPassword, func(block *pem.Block) error {
err = lib.ReadAsPEMFromFiles(files, *dumpType, tty.ReadPassword, func(block *pem.Block, format string) error {
block.Headers = nil
return pem.Encode(stdout, block)
})
} else {
err = lib.ReadAsX509FromFiles(files, *dumpType, tty.ReadPassword, func(cert *x509.Certificate, err error) error {
err = lib.ReadAsX509FromFiles(files, *dumpType, tty.ReadPassword, func(cert *x509.Certificate, format string, err error) error {
if err != nil {
return fmt.Errorf("error parsing block: %s\n", strings.TrimSuffix(err.Error(), "\n"))
} else {
result.Certificates = append(result.Certificates, cert)
result.Formats = append(result.Formats, format)
}
return nil
})
Expand All @@ -107,6 +108,7 @@ func Run(args []string, tty terminal.Terminal) int {
} else {
for i, cert := range result.Certificates {
fmt.Fprintf(stdout, "** CERTIFICATE %d **\n", i+1)
fmt.Fprintf(stdout, "Input Format: %s\n", result.Formats[i])
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert, terminalWidth, *verbose))
}
}
Expand Down Expand Up @@ -156,6 +158,7 @@ func Run(args []string, tty terminal.Terminal) int {

for i, cert := range result.Certificates {
fmt.Fprintf(stdout, "** CERTIFICATE %d **\n", i+1)
fmt.Fprintf(stdout, "Input Format: %s\n", result.Formats[i])
fmt.Fprintf(stdout, "%s\n\n", lib.EncodeX509ToText(cert, terminalWidth, *verbose))
}
lib.PrintVerifyResult(stdout, *result.VerifyResult)
Expand All @@ -176,7 +179,7 @@ func Run(args []string, tty terminal.Terminal) int {
defer file.Close()

chain := []*x509.Certificate{}
err = lib.ReadAsX509FromFiles([]*os.File{file}, *verifyType, tty.ReadPassword, func(cert *x509.Certificate, err error) error {
err = lib.ReadAsX509FromFiles([]*os.File{file}, *verifyType, tty.ReadPassword, func(cert *x509.Certificate, format string, err error) error {
if err != nil {
return err
} else {
Expand Down
1 change: 1 addition & 0 deletions cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ t/DtcM/GpAhBbLP9Tk7kPB41v5fRIxVDo50Iz/qvkr37pQ4RsejSFg==
`

const expectedVerbose string = `** CERTIFICATE 1 **
Input Format: PEM
Serial: 4096
Valid: 2017-07-19 16:50 UTC to 2017-07-29 16:50 UTC
Signature: SHA256-RSA
Expand Down
37 changes: 19 additions & 18 deletions lib/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func errorFromErrors(errs []error) error {
// data may be in plain-text PEM files, DER-encoded certificates or PKCS7
// envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to PEM
// blocks and passed to the callback.
func ReadAsPEMFromFiles(files []*os.File, format string, password func(string) string, callback func(*pem.Block) error) error {
func ReadAsPEMFromFiles(files []*os.File, format string, password func(string) string, callback func(*pem.Block, string) error) error {
var errs []error
for _, file := range files {
reader := bufio.NewReaderSize(file, 4)
Expand All @@ -109,7 +109,7 @@ func ReadAsPEMFromFiles(files []*os.File, format string, password func(string) s
// be in plain-text PEM files, DER-encoded certificates or PKCS7 envelopes, or
// PKCS12/JCEKS keystores. All inputs will be converted to PEM blocks and
// passed to the callback.
func ReadAsPEM(readers []io.Reader, format string, password func(string) string, callback func(*pem.Block) error) error {
func ReadAsPEM(readers []io.Reader, format string, password func(string) string, callback func(*pem.Block, string) error) error {
errs := []error{}
for _, r := range readers {
reader := bufio.NewReaderSize(r, 4)
Expand All @@ -130,7 +130,7 @@ func ReadAsPEM(readers []io.Reader, format string, password func(string) string,
// inputs. Input data may be in plain-text PEM files, DER-encoded certificates
// or PKCS7 envelopes, or PKCS12/JCEKS keystores. All inputs will be converted
// to X.509 certificates (private keys are skipped) and passed to the callback.
func ReadAsX509FromFiles(files []*os.File, format string, password func(string) string, callback func(*x509.Certificate, error) error) error {
func ReadAsX509FromFiles(files []*os.File, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error {
errs := []error{}
for _, file := range files {
reader := bufio.NewReaderSize(file, 4)
Expand All @@ -151,7 +151,7 @@ func ReadAsX509FromFiles(files []*os.File, format string, password func(string)
// data may be in plain-text PEM files, DER-encoded certificates or PKCS7
// envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to X.509
// certificates (private keys are skipped) and passed to the callback.
func ReadAsX509(readers []io.Reader, format string, password func(string) string, callback func(*x509.Certificate, error) error) error {
func ReadAsX509(readers []io.Reader, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error {
errs := []error{}
for _, r := range readers {
reader := bufio.NewReaderSize(r, 4)
Expand All @@ -168,20 +168,20 @@ func ReadAsX509(readers []io.Reader, format string, password func(string) string
return errorFromErrors(errs)
}

func pemToX509(callback func(*x509.Certificate, error) error) func(*pem.Block) error {
return func(block *pem.Block) error {
func pemToX509(callback func(*x509.Certificate, string, error) error) func(*pem.Block, string) error {
return func(block *pem.Block, format string) error {
switch block.Type {
case "CERTIFICATE":
cert, err := x509.ParseCertificate(block.Bytes)
return callback(cert, err)
return callback(cert, format, err)
case "PKCS7":
certs, err := pkcs7.ExtractCertificates(block.Bytes)
if err == nil {
for _, cert := range certs {
return callback(cert, nil)
return callback(cert, format, nil)
}
} else {
return callback(nil, err)
return callback(nil, format, err)
}
case "CERTIFICATE REQUEST":
fmt.Println(red.SprintfFunc()("warning: certificate requests are not supported"))
Expand All @@ -191,19 +191,20 @@ func pemToX509(callback func(*x509.Certificate, error) error) func(*pem.Block) e
}

// readCertsFromStream takes some input and converts it to PEM blocks.
func readCertsFromStream(reader io.Reader, filename string, format string, password func(string) string, callback func(*pem.Block) error) error {
func readCertsFromStream(reader io.Reader, filename string, format string, password func(string) string, callback func(*pem.Block, string) error) error {
headers := map[string]string{}
if filename != "" && filename != os.Stdin.Name() {
headers[fileHeader] = filename
}

switch strings.TrimSpace(format) {
format = strings.TrimSpace(format)
switch format {
case "PEM":
scanner := pemScanner(reader)
for scanner.Scan() {
block, _ := pem.Decode(scanner.Bytes())
block.Headers = mergeHeaders(block.Headers, headers)
err := callback(block)
err := callback(block, format)
if err != nil {
return err
}
Expand All @@ -217,7 +218,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
x509Certs, err0 := x509.ParseCertificates(data)
if err0 == nil {
for _, cert := range x509Certs {
err := callback(EncodeX509ToPEM(cert, headers))
err := callback(EncodeX509ToPEM(cert, headers), format)
if err != nil {
return err
}
Expand All @@ -227,7 +228,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
p7bBlocks, err1 := pkcs7.ParseSignedData(data)
if err1 == nil {
for _, block := range p7bBlocks {
err := callback(pkcs7ToPem(block, headers))
err := callback(pkcs7ToPem(block, headers), format)
if err != nil {
return err
}
Expand All @@ -246,7 +247,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
}
for _, block := range blocks {
block.Headers = mergeHeaders(block.Headers, headers)
err := callback(block)
err := callback(block, format)
if err != nil {
return err
}
Expand All @@ -259,7 +260,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
}
for _, alias := range keyStore.ListCerts() {
cert, _ := keyStore.GetCert(alias)
err := callback(EncodeX509ToPEM(cert, mergeHeaders(headers, map[string]string{nameHeader: alias})))
err := callback(EncodeX509ToPEM(cert, mergeHeaders(headers, map[string]string{nameHeader: alias})), format)
if err != nil {
return err
}
Expand All @@ -277,12 +278,12 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
return fmt.Errorf("problem reading key: %s\n", err)
}

if err := callback(block); err != nil {
if err := callback(block, format); err != nil {
return err
}

for _, cert := range certs {
if err = callback(EncodeX509ToPEM(cert, mergedHeaders)); err != nil {
if err = callback(EncodeX509ToPEM(cert, mergedHeaders), format); err != nil {
return err
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type SimpleVerification struct {

type SimpleResult struct {
Certificates []*x509.Certificate `json:"certificates"`
Formats []string
VerifyResult *SimpleVerification `json:"verify_result,omitempty"`
TLSConnectionState *tls.ConnectionState
CertificateRequestInfo *tls.CertificateRequestInfo
Expand Down Expand Up @@ -94,7 +95,7 @@ func caBundle(caPath string) (*x509.CertPool, error) {
// TODO: The JDK trust store ships with this password.
return "changeit"
},
func(cert *x509.Certificate, err error) error {
func(cert *x509.Certificate, format string, err error) error {
if err != nil {
return fmt.Errorf("error parsing CA bundle: %s\n", err)
} else {
Expand Down
3 changes: 3 additions & 0 deletions tests/dump-cert-chain-to-text.t
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ Dump a live cert chain (squareup-chain.crt)
$ certigo --verbose dump squareup-chain.crt
** CERTIFICATE 1 **
Input Format: PEM
Serial: 260680855742043049380997676879525498489
Valid: 2016-07-15 20:15 UTC to 2017-07-31 20:45 UTC
Signature: SHA256-RSA
Expand Down Expand Up @@ -148,6 +149,7 @@ Dump a live cert chain (squareup-chain.crt)
\tgosq.co, www.gosq.co (esc)
** CERTIFICATE 2 **
Input Format: PEM
Serial: 30215777750102225331854468774
Valid: 2014-12-15 15:25 UTC to 2030-10-15 15:55 UTC
Signature: SHA256-RSA
Expand Down Expand Up @@ -176,6 +178,7 @@ Dump a live cert chain (squareup-chain.crt)
\tServer Auth (esc)
** CERTIFICATE 3 **
Input Format: PEM
Serial: 1372799044
Valid: 2014-09-22 17:14 UTC to 2024-09-23 01:31 UTC
Signature: SHA256-RSA
Expand Down
1 change: 1 addition & 0 deletions tests/dump-leaf-to-not-verbose.t
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Dump an example certificate (example-leaf.crt)
$ certigo dump example-leaf.crt
** CERTIFICATE 1 **
Input Format: PEM
Valid: 2016-06-10 22:14 UTC to 2023-04-15 22:14 UTC
Subject:
\tC=US, ST=CA, O=certigo, OU=example, CN=example-leaf (esc)
Expand Down
1 change: 1 addition & 0 deletions tests/dump-leaf-to-text.t
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Dump an example certificate (example-leaf.crt)
$ certigo --verbose dump example-leaf.crt
** CERTIFICATE 1 **
Input Format: PEM
Serial: 15384458167827828543
Valid: 2016-06-10 22:14 UTC to 2023-04-15 22:14 UTC
Signature: SHA256-RSA
Expand Down
2 changes: 2 additions & 0 deletions tests/dump-name-constraints-to-text.t
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Dump an example certificate with name constraints (example-name-constraints.crt)
$ certigo --verbose dump example-name-constraints.crt
** CERTIFICATE 1 **
Input Format: PEM
Serial: 13776854720312847553
Valid: 2017-08-18 19:48 UTC to 2024-06-22 19:48 UTC
Signature: SHA256-RSA (self-signed)
Expand Down Expand Up @@ -88,6 +89,7 @@ Dump an example certificate with name constraints (example-name-constraints.crt)
\tCert Sign (esc)
** CERTIFICATE 2 **
Input Format: PEM
Serial: 0
Valid: 2011-12-06 13:49 UTC to 2031-12-01 13:49 UTC
Signature: SHA1-RSA (self-signed)
Expand Down
1 change: 1 addition & 0 deletions tests/dump-small-key-to-text.t
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Dump an example certificate (example-leaf.crt)
$ certigo --verbose dump example-small-key.crt
** CERTIFICATE 1 **
Input Format: PEM
Serial: 14381893493177441266
Valid: 2016-06-10 22:14 UTC to 2023-04-15 22:14 UTC
Signature: SHA256-RSA (self-signed)
Expand Down
1 change: 1 addition & 0 deletions tests/dump-spiffe-cert-to-text.t
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Dump a SPIFFE example certificate (example-spiffe.crt)
$ certigo --verbose dump example-spiffe.crt
** CERTIFICATE 1 **
Input Format: PEM
Serial: 4096
Valid: 2017-07-19 16:50 UTC to 2017-07-29 16:50 UTC
Signature: SHA256-RSA
Expand Down

0 comments on commit f81df5c

Please sign in to comment.