sortpem

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2018 License: MIT Imports: 17 Imported by: 2

README

SortPEM API

Sorting utility for PEM files. Failing to remember what order to put the certificate and its intermediates in? And what intermediate should we include? Wonder no longer, and let sortpem resolve the chain for you.

It is assumed your system receives software updates, and it has a recent copy of the trusted certificate bundle for your operating system. sortpem does not provide root certificates; there are many sources out there that can provide you that information.

If you wish to use a custom trusted roots bundle (in PEM format), you can pass the -ca <file> flag to sortpem.

Options

Most of the flags are compatible with the sort(1) utility:

-D    Enable debug logging
-a    Output all blocks, not only the ones matching -t
-c    Count blocks
-ca string
      CA file
-d    Dump text output of decoded PEM block
-o string
      Print the output to a file in stead of standard output
-p string
      Preset (use "list" for an overview)
-r    Reverse sort
-root
      Include root certificate
-s    Stable sort
-t value
      Type of block order and filter (regular expression(s))
-u    Unique blocks

Presets

There are presets available that sets a combination of default options based on the chose preset:

certs    -t "^CERTIFICATE$" -R
keys     -t "PRIVATE KEY$"
nginx    -t "^CERTIFICATE$" -t "PRIVATE KEY$"
haproxy  -t "^CERTIFICATE$" -t "PRIVATE KEY$" -R

Example

Sort a PEM bundle, CERTIFICATEs first, then any PRIVATE KEY:

user@host:~$ ls -1 testdata/*.crt testdata/endpoint.key
testdata/endpoint.crt
testdata/endpoint.key 
testdata/intermediate.crt 
testdata/issuer.crt 
testdata/root.crt

# We have a self-signed root:
user@host:~$ openssl x509 -in testdata/root.crt -noout -subject -issuer
subject= /CN=Test Root
issuer= /CN=Test Root

# By default, the root certificate is omitted (enabled -d which decodes blocks):
user@host:~$ cat testdata/*.crt testdata/endpoint.key | sortpem -d | grep Subject:
  Subject:    CN=endpoint.example.org,L=IL
  Subject:    CN=Test Intermediate
  Subject:    CN=Test Issuer

# We can include it, with -root:
user@host:~$ cat testdata/*.crt testdata/endpoint.key | sortpem -root -d | grep Subject:
  Subject:    CN=endpoint.example.org,L=IL
  Subject:    CN=Test Intermediate
  Subject:    CN=Test Issuer
  Subject:    CN=Test Root

# The private key is in there too, by the way:
user@host:~$ cat testdata/*.crt testdata/endpoint.key | sortpem -root | grep 'BEGIN '
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----

# Download a public certificate:
user@host:~$ echo "" | openssl s_client -connect google.com:443 -showcerts > testdata/google.com.crt
depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3
verify error:num=20:unable to get local issuer certificate
verify return:0
DONE

# It sent us 2 certificates:
user@host:~$ grep -c 'BEGIN CERTIFICATE' testdata/google.com.crt
2

# Inspect them:
user@host:~$ sortpem -d testdata/google.com.crt | grep Subject:
  Subject:    CN=*.google.com,O=Google LLC,L=Mountain View,ST=California,C=US
  Subject:    CN=Google Internet Authority G3,O=Google Trust Services,C=US

# Get the full chain, including root:
user@host:~$ sortpem -root -d testdata/google.com.crt | grep Subject:
  Subject:    CN=*.google.com,O=Google LLC,L=Mountain View,ST=California,C=US
  Subject:    CN=Google Internet Authority G3,O=Google Trust Services,C=US
  Subject:    CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeAll added in v1.0.1

func DecodeAll(data []byte) (blocks []*pem.Block, rest []byte)

DecodeAll decodes all PEM blocks in data, leaving all non-PEM data in rest.

func IsSelfSigned added in v0.99.0

func IsSelfSigned(cert *x509.Certificate) bool

IsSelfSigned checks for a self-signed certificate.

func IsSignedBy added in v0.99.0

func IsSignedBy(cert, root *x509.Certificate) (ok bool)

IsSignedBy does a check if cert is signed by root. Do not ever use this function for any other purpose than sorting, as it's skipping a lot of important steps from 5280 such as verifying basic constraints, validity or path depths (since we're only interested in sorting certificates).

func KeyBelongsTo added in v0.99.0

func KeyBelongsTo(cert *x509.Certificate, key interface{}) (ok bool)

KeyBelongsTo checks if the cert is signed by the key. The key can be any supported public or private key. See PrivateKeyBelongsTo for how private keys are handled.

func PrivateKeyBelongTo added in v0.99.0

func PrivateKeyBelongTo(cert *x509.Certificate, key interface{}) (ok bool)

PrivateKeyBelongTo is like KeyBelongsTo, but only for private keys. Note that we're just comparing public key parts of the passed key. There are no checks performed to see if the public key part of the private key is actually valid (since we should only be using this function for sorting).

Types

type CertPool

type CertPool struct {
	// contains filtered or unexported fields
}

CertPool is a set of certificates.

func NewCertPool

func NewCertPool() *CertPool

NewCertPool returns a new, empty CertPool.

func SystemCertPool

func SystemCertPool() (*CertPool, error)

SystemCertPool returns a copy of the system cert pool.

Any mutations to the returned pool are not written to disk and do not affect any other pool.

New changes in the the system cert pool might not be reflected in subsequent calls.

func (*CertPool) AddCert

func (pool *CertPool) AddCert(cert *x509.Certificate)

AddCert adds a certificate to a pool.

func (*CertPool) AppendCertsFromPEM

func (pool *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool)

AppendCertsFromPEM attempts to parse a series of PEM encoded certificates. It appends any certificates found to s and reports whether any certificates were successfully parsed.

On many Linux systems, /etc/ssl/cert.pem will contain the system wide set of root CAs in a format suitable for this function.

func (*CertPool) Contains added in v0.99.0

func (pool *CertPool) Contains(cert *x509.Certificate) bool

Contains checks if the cert is a trusted root certificate in this pool.

func (*CertPool) Subjects

func (pool *CertPool) Subjects() [][]byte

Subjects returns a list of the DER-encoded subjects of all of the certificates in the pool.

type Sorter added in v0.99.0

type Sorter struct {
	// Blocks are our PEM blocks.
	Blocks []*pem.Block

	// Roots are our trusted root certificates. If nil, the ResolveRoots and
	// ExcludeRoots function will use the system trusted root certificates.
	Roots *CertPool

	// Order of our blocks.
	Order []string
	// contains filtered or unexported fields
}

Sorter can help sort slices of PEM blocks. You can use this struct directly, but the certificate resolution won't be cached, if you wish to use a cached version of the Sorter, invoke New.

The sorter deploys the following sorting strategy: * Compare the block types A and B:

  • If A and B are certificates:
  • If A is an invalid certificate, sort after
  • If B is an invalid certificate, sort before
  • If A is signed by B, sort before
  • If B is signed by A, sort after
  • If either one of A and B are a certificate and the other a private key:
  • If key A belongs to certificate B, reverse sort against Order list
  • If key B belongs to certificate A, forward sort against Order list

* Lookup the block type of A and B against the Order list, then:

  • If A is unknown, sort after
  • If B is unknown, sort before
  • Compare if A is before B in the order list

func New added in v0.99.0

func New(blocks []*pem.Block) *Sorter

New sorter for the PEM block slice.

func NewBytes added in v1.0.1

func NewBytes(data []byte) *Sorter

NewBytes returns a sorter for all PEM blocks in data.

func (*Sorter) ExcludeRoots added in v0.99.0

func (sorter *Sorter) ExcludeRoots() (changed bool)

ExcludeRoots checks if the blocks in sorter are a root certificate, and if they are, they will be removed.

func (*Sorter) Len added in v0.99.0

func (sorter *Sorter) Len() int

Len is the number of Blocks contained.

func (*Sorter) Less added in v0.99.0

func (sorter *Sorter) Less(i, j int) (less bool)

Less comapares Blocks with index i and j.

func (*Sorter) ResolveRoots added in v0.99.0

func (sorter *Sorter) ResolveRoots() (changed bool)

ResolveRoots checks if the blocks in sorter have a root certificate and if they do not, it will attempt to resolve the root certificate for the passed certificates.

func (*Sorter) Swap added in v0.99.0

func (sorter *Sorter) Swap(i, j int)

Swap Blocks with index i and j.

func (*Sorter) Unique added in v1.0.0

func (sorter *Sorter) Unique() (blocks []*pem.Block)

Unique returns only unique blocks.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL