Documentation
¶
Overview ¶
Package utils with functions to get the outbound network interface
Package utils with logging configuration ¶
Package watcher that handles file renames ¶
Package utils with certificate management helpers ¶
Package utils with key management for certificates and authn
Index ¶
- Constants
- Variables
- func ComparePrivKey(priv1 crypto.PrivateKey, priv2 crypto.PrivateKey) bool
- func CreateCACert(cn, country, province, locality, orgName string, validity time.Duration, ...) (caCert *x509.Certificate, err error)
- func CreateCertFromTemplate(template *x509.Certificate, validity time.Duration, caCert *x509.Certificate, ...) (*x509.Certificate, error)
- func CreateClientCert(clientID string, ou string, country, province, locality, orgName string, ...) (x509Cert *x509.Certificate, err error)
- func CreateServerCert(cn string, ou string, country, province, locality, orgName string, ...) (x509Cert *x509.Certificate, err error)
- func Decode(value any, arg any) (err error)
- func DecodeAsBool(value any) bool
- func DecodeAsInt(value any) int
- func DecodeAsNumber(value any) float32
- func DecodeAsObject(value any, object interface{}) error
- func DecodeAsString(value any, maxlen int) string
- func DecodeAsUint(value any) uint
- func FormatAge(dateStr string) (age string)
- func FormatDateTime(dateStr string, format ...string) string
- func FormatMSE(mse int64, short bool) string
- func FormatNowUTCMilli() string
- func FormatUTCMilli(t time.Time) string
- func GetBearerToken(req *http.Request) (string, error)
- func GetIP4Subnets(only24 bool) ([]string, error)
- func GetInterfaces(address string) ([]net.Interface, error)
- func GetOutboundIP(destination string) net.IP
- func GetOutboundInterface(address string) (interfaceName string, macAddress string, ipAddr net.IP)
- func LoadCACert(caCertPath string) (caCert *x509.Certificate, err error)
- func LoadCreateKeyPair(keyFile string, keyType KeyType) (privKey crypto.PrivateKey, pubKey crypto.PublicKey, err error)
- func LoadPrivateKey(keyPath string) (privKey crypto.Signer, pubKey crypto.PublicKey, err error)
- func LoadPublicKey(keyPath string) (pubKey crypto.PublicKey, err error)
- func LoadTLSCert(certPEMPath, keyPEMPath string) (tlsCert *tls.Certificate, err error)
- func LoadX509Cert(pemPath string) (cert []*x509.Certificate, err error)
- func MapKeys[K comparable, V any](mm map[K]V) []K
- func NewEcdsaKey() (*ecdsa.PrivateKey, *ecdsa.PublicKey)
- func NewEd25519Key() (ed25519.PrivateKey, ed25519.PublicKey)
- func NewFileLogger(logfileName string, asJSON bool) (*slog.Logger, *os.File)
- func NewKey(keyType KeyType) (crypto.Signer, crypto.PublicKey)
- func NewRsaKey() (*rsa.PrivateKey, *rsa.PublicKey)
- func OrderedMapKeys[K constraints.Ordered, V any](mm map[K]V) []K
- func PemToDer(pemString string) ([]byte, error)
- func PrivateKeyFromPem(privatePEM string) (privKey crypto.Signer, pubKey crypto.PublicKey, err error)
- func PrivateKeyToPEM(privKey crypto.PrivateKey) string
- func PublicKeyFromPem(publicPEM string) (pubKey crypto.PublicKey, err error)
- func PublicKeyToPem(pubKey crypto.PublicKey) (pemKey string)
- func SavePrivateKey(privKey crypto.PrivateKey, pemPath string) error
- func SavePublicKey(pubKey crypto.PublicKey, pemPath string) error
- func SaveTLSCert(tlsCert *tls.Certificate, certPemPath, keyPemPath string) error
- func SaveX509Cert(cert *x509.Certificate, pemPath string) error
- func SaveX509CertChain(certChain []*x509.Certificate, pemPath string) error
- func SetLogging(levelName string, logFilename string) *slog.Logger
- func Sign(msg []byte, k crypto.PrivateKey) (signature []byte, err error)
- func StartHeartbeat(interval time.Duration, fn func()) (stopFn func())
- func Substitute(s string, vars map[string]string) string
- func TLSCertFromPEM(tlsPem string) (*tls.Certificate, error)
- func TLSCertToPEM(tlsCert *tls.Certificate) (certPem string, keyPem string)
- func TLSCertToX509(tlsCert *tls.Certificate) ([]*x509.Certificate, crypto.PrivateKey)
- func Verify(msg []byte, signature []byte, k crypto.PublicKey) (valid bool)
- func VerifyCert(cert *x509.Certificate, caCertPool *x509.CertPool) (cn string, err error)
- func WaitForSignal()
- func WatchFile(path string, handler func() error) (*fsnotify.Watcher, error)
- func WriteError(w http.ResponseWriter, err error, code int)
- func WriteReply(w http.ResponseWriter, handled bool, data any, err error)
- func X509CertFromPEM(certPem string) (cert *x509.Certificate, err error)
- func X509CertToPEM(cert *x509.Certificate) (certPem string)
- func X509CertToTLS(cert *x509.Certificate, privKey crypto.PrivateKey) *tls.Certificate
- func X509ChainFromPEM(certPem string) (chain []*x509.Certificate, err error)
- func X509ChainToPEM(chain []*x509.Certificate) (certStr string)
- func X509ChainToTLS(chain []*x509.Certificate, privKey crypto.PrivateKey) *tls.Certificate
- type AsyncReceiver
- type KeyType
Constants ¶
const ( COReset = "\033[0m" CORed = "\033[31m" COGreen = "\033[32m" COYellow = "\033[33m" COBlue = "\033[34m" COPurple = "\033[35m" COCyan = "\033[36m" COGray = "\033[37m" COWhite = "\033[97m" )
Console ASCII commands to control colors See also: https://www.codequoi.com/en/coloring-terminal-text-tput-and-ansi-escape-sequences/
const ( CBBlack = "\033[40m" CBRed = "\033[41m" CBGreen = "\033[42m" CBYellow = "\033[43m" CBBlue = "\033[44m" CBGray = "\033[47m" CBWhite = "\033[41m" )
const ( WrapOff = "\033[?7l" WrapOn = "\033[?7h" )
Variables ¶
var MilliTimeFormat = "2006-01-02 15:04:05.000 MST" // millisecond
var VerboseTimeFormat = time.RFC1123 // full date-time
var WeekTimeFormat = "Mon 02, 15:04:05 MST" // for the last 7 days
each of these formats can be updated
var YearTimeFormat = "2006-01-02, 15:04:05 MST" // full date-time
Functions ¶
func ComparePrivKey ¶
func ComparePrivKey(priv1 crypto.PrivateKey, priv2 crypto.PrivateKey) bool
Compare two unknqon private keys.
The keys must implement the 'Equal' method.
func CreateCACert ¶
func CreateCACert( cn, country, province, locality, orgName string, validity time.Duration, caPrivKey crypto.PrivateKey, caPubKey crypto.PublicKey) ( caCert *x509.Certificate, err error)
CreateCACert creates a CA certificate for signing certificates and digital signatures. Intended for self-signed server, client certificates and message signing. Source: https://shaneutt.com/blog/golang-ca-and-signed-cert-go/
func CreateCertFromTemplate ¶
func CreateCertFromTemplate(template *x509.Certificate, validity time.Duration, caCert *x509.Certificate, caPrivKey crypto.PrivateKey) (*x509.Certificate, error)
Create a new certificate from the given template. This uses the template PublicKey in the new certificate
func CreateClientCert ¶
func CreateClientCert(clientID string, ou string, country, province, locality, orgName string, validity time.Duration, pubKey crypto.PublicKey, caCert *x509.Certificate, caKey crypto.PrivateKey) ( x509Cert *x509.Certificate, err error)
Create a client certificate signed by the given intermediary or CA cert intended for testing, not for production
clientID is the certificate common name, usually the clientID ou the organization the client belongs to country, province, locality, orgName are optional to include validity of the client cert. Required. pubKey is the client's public key for this certificate caCert, caKey are the signing CA's certificate and private key
func CreateServerCert ¶
func CreateServerCert( cn string, ou string, country, province, locality, orgName string, names []string, validity time.Duration, serverPubKey crypto.PublicKey, caCert *x509.Certificate, caPrivKey crypto.PrivateKey, ) (x509Cert *x509.Certificate, err error)
Create a server certificate signed by the given intermediary or CA cert
The provided x509 certificate can be converted to a PEM text with:
certPEM = certs.X509CertToPEM(cert)
To create a TLS cert:
tlsCert = X509CertToTLS(x509Cert, privKey) cn is the server common name ou is the organizational unit of the certificate country, province, locality, orgName are optional to include names are the SAN names to include with the certificate, localhost and 127.0.0.1 are always added validity is the duration the cert is valid for. Required. serverPubKey contains the server's public key to include in the certificate caCert is the CA certificate used to sign the certificate caKey is the CA private key used to sign certificate
func Decode ¶
Decode converts the any-type to the given interface type. If the output type is a native type then also consider using one of the DecodeAs... methods as these are likely more performant. This returns an error if conversion fails.
func DecodeAsBool ¶
DecodeAsBool converts the value to a boolean. If value is already a boolean then it is returned as-is.
func DecodeAsInt ¶
DecodeAsInt converts the value to an integer. This accepts int, int64, *int, bool, uint, float32/64 If value is already an integer then it is returned as-is. If value > int (eg int64) then the result is unpredicable
func DecodeAsNumber ¶
DecodeAsNumber converts the value to a float32 number. If value is already a float32 then it is returned as-is.
func DecodeAsObject ¶
DecodeAsObject converts the value to an object. If the object is of the same type then it is copied otherwise a json marshal/unmarshal is attempted for a deep conversion.
func DecodeAsString ¶
DecodeAsString converts the value to a string if value is already a string then it is returned as-is if maxlen is provided then limit the resulting length and add ... if exceeded. Use 0 for all.
func DecodeAsUint ¶
DecodeAsUInt converts the value to an unsigned integer. This accepts uint, uint64, *uint, bool, uint, float32/64 If value is already an integer then it is returned as-is. If value > int (eg int64) then the result is unpredicable
func FormatAge ¶
FormatAge converts the given time to the current short age format h m s ago
If time is less than an hour: minutes seconds ago If time is less than a day: hours minutes ago If time is less than a month: days hours minutes ago If time is more than a month: days hours ago
func FormatDateTime ¶
FormatDateTime format an iso date/time string into a human readable format value is an iso timestamp Format:
"" default is the year time format: YYYY-MM-DD, HH:MM:SS TZ "S" is the shortest possible format depending on device "V" is the verbose format "AGE" is the age format like "5m 30s ago"
format is default RFC822, or use "S" for a short format "weekday, time" if less than a week old
func FormatMSE ¶
FormatMSE returns a human-readable string into local time in millisec since epoc
These are in timezone: time.Now().Zone() The short format is: StampMilli: Jan _2 15:04:05.000 (local time) The long format is: YYYY-MM-DD HH:MM:SS TZ
func FormatNowUTCMilli ¶
func FormatNowUTCMilli() string
FormatNowUTCMilli returns the current time in UTC milliseconds
func FormatUTCMilli ¶
FormatUTCMilli returns the given time in UTC with milliseconds, yyyy-mm-ddThh:mm:ss.000Z
func GetBearerToken ¶
GetBearerToken returns the bearer token from the HTTP request authorization header Returns an error if no token present or token isn't a bearer token
func GetIP4Subnets ¶
GetIP4Subnets of the valid IPv4 interfaces. Returns list of one or more ip/subnet strings.
This is often a single subnet unless there is wifi, multiple cards or vlans ¶
The 'only24' flag indicates to only include /24 subnets (recommended)
func GetInterfaces ¶
GetInterfaces returns a list of active network interfaces excluding the loopback interface
address to only return the interface that serves the given IP address
func GetOutboundIP ¶
GetOutboundIP returns the default outbound IP address to reach the given hostname. This uses 1.1.1.1 as the default destination. TODO: use the default gateway address instead so this works without internet access.
Use a local hostname if a subnet other than the default one should be used. Use "" for the default route address
destination to reach or "" to use 1.1.1.1 (no connection will be established)
func GetOutboundInterface ¶
GetOutboundInterface Get preferred outbound network interface of this machine Credits: https://stackoverflow.com/questions/23558425/how-do-i-get-the-local-ip-address-in-go and https://qiita.com/shaching/items/4c2ee8fd2914cce8687c
func LoadCACert ¶
func LoadCACert(caCertPath string) (caCert *x509.Certificate, err error)
Load a saved CA certificate from file if caKeyPath then ignore the private key This returns an error if no valid certificate or key is found.
func LoadCreateKeyPair ¶
func LoadCreateKeyPair(keyFile string, keyType KeyType) ( privKey crypto.PrivateKey, pubKey crypto.PublicKey, err error)
LoadCreateKeyPair loads a public/private key pair from file.
If the key doesn't exist a new key is created using the given keyType.
keysFile is the location of the key file to load or create. Required. keyType is the type of key when creating a new key
func LoadPrivateKey ¶
LoadPrivateKey loads a public/private key pair from file. This returns nil if the key type cannot be determined
keyPath is the path to the file containing the key
func LoadPublicKey ¶
LoadPublicKey loads a public key from file. This returns nil if the key type cannot be determined
keyPath is the path to the file containing the key
func LoadTLSCert ¶
func LoadTLSCert(certPEMPath, keyPEMPath string) (tlsCert *tls.Certificate, err error)
LoadTLSCert loads the TLS certificate from PEM formatted files. TLS certificates are a container for both X509 certificate and private key.
Intended to load the certificate and key for servers, or for clients such as IoT devices that use client certificate authentication. The idprov service issues this type of certificate during IoT device provisioning.
This is simply a wrapper around tls.LoadX509KeyPair. See also SaveTLSCertToPEM.
If loading fails, this returns nil as certificate pointer
func LoadX509Cert ¶
func LoadX509Cert(pemPath string) (cert []*x509.Certificate, err error)
LoadX509Cert loads the x509 certificate chain from a PEM file format.
Intended to load the CA and server certificates.
pemPath is the full path to the X509 PEM file.
func NewEcdsaKey ¶
func NewEcdsaKey() (*ecdsa.PrivateKey, *ecdsa.PublicKey)
func NewEd25519Key ¶
func NewEd25519Key() (ed25519.PrivateKey, ed25519.PublicKey)
NewEd25519Key creates a new ED25519 key
func NewFileLogger ¶
NewFileLogger returns a new file logger that forks to stdout This returns the logger and the file.
func NewKey ¶
NewKey creates a new key of the given type This returns a private key that supports signing and a public key.
func OrderedMapKeys ¶
func OrderedMapKeys[K constraints.Ordered, V any](mm map[K]V) []K
OrderedMapKeys returns an ordered slice of keys
func PrivateKeyFromPem ¶
func PrivateKeyFromPem(privatePEM string) ( privKey crypto.Signer, pubKey crypto.PublicKey, err error)
PrivateKeyFromPem reads the key-pair from the PEM private key. This returns an error if the PEM is not a valid key.
func PrivateKeyToPEM ¶
func PrivateKeyToPEM(privKey crypto.PrivateKey) string
PrivateKeyToPEM returns the PEM encoded private key
func PublicKeyFromPem ¶
PublicKeyFromPem reads the public key from the PEM data. This returns an error if the PEM is not a valid public key
func PublicKeyToPem ¶
PublicKeyToPem returns the PEM encoded public key if available
func SavePrivateKey ¶
func SavePrivateKey(privKey crypto.PrivateKey, pemPath string) error
SavePrivateKeyToFile saves the private key to file in PEM format.
The file permissions are set to 0400, current user only, read-write permissions. If the directory does not exist it will becreated
Returns error in case the key is invalid or file cannot be written.
func SavePublicKey ¶
SavePublicKeyToFile saves the public key to file in PEM format. The file permissions are set to 0644, current user can write, rest can read.
If the directory does not exist it will be created
Returns error in case the public key is invalid or file cannot be written.
func SaveTLSCert ¶
func SaveTLSCert(tlsCert *tls.Certificate, certPemPath, keyPemPath string) error
SaveTLSCert creates and saves the TLS certificate to a x509 and key file in PEM format.
If the TLS certificate contains a chain then all certificates in the chain are included in the cert file.
Intended for saving a certificate received from provisioning or created for testing. If the directory doesn't exist it will be created with permissions 755 The certificate file will be written with permissions 0444. Existing file will be removed first. The key file, if provided, will be written with permissions 0400
tlsCert is the obtained TLS certificate whose parts to save certPemPath the file to save the X509 certificate to in PEM format keyPemPath the file to save the private key to in PEM format. "" to not save the key.
func SaveX509Cert ¶
func SaveX509Cert(cert *x509.Certificate, pemPath string) error
SaveX509Cert saves the x509 certificate to file in PEM format.
If the directory doesn't exist it will be created with permissions 755 The certificate file will be written with permissions 0444. Existing file will be removed first.
Clients that receive a client certificate from provisioning can use this to save the provided certificate to file. If the file exists it is removed first.
func SaveX509CertChain ¶
func SaveX509CertChain(certChain []*x509.Certificate, pemPath string) error
SaveX509CertChain saves the x509 certificate chain to file in PEM format. If the file exists it is removed first.
func SetLogging ¶
SetLogging initializes the global logger
func Sign ¶
func Sign(msg []byte, k crypto.PrivateKey) (signature []byte, err error)
Sign returns the signature of a message signed using this key This signs the SHA256 hash of the message this requires a private key to be created or imported
func StartHeartbeat ¶
StartHeartbeat is a helper that runs a heartbeat process in the background.
This returns a stop function to end the heartbeat loop. If the heartbeat function is running then the heartbeat will wait until it completes. If the heartbeat is no longer running then the stop function returns immediately.
The timer pauses when the heartbeat function is running. If there is a temporary delay in the heartbeat there is no risk of overrun.
interval is the time to wait in between heartbeat invocations fn is the heartbeat function
func Substitute ¶
Substitute substitutes the variables in a string Variables are define with curly brackets, eg: "this is a {variableName}"
func TLSCertFromPEM ¶
func TLSCertFromPEM(tlsPem string) (*tls.Certificate, error)
TLSCertFromPEM converts a PEM text to a TLS certificate.
This support a concatenated PEM text. If the provided PEM only contains a certificate then the TLS wont have a private key part.
func TLSCertToPEM ¶
func TLSCertToPEM(tlsCert *tls.Certificate) (certPem string, keyPem string)
TLSCertToPEM converts a TLS certificate to a certificate and a private key PEM string. If the TLS cert does not contain a private key it is returned as empty.
func TLSCertToX509 ¶
func TLSCertToX509(tlsCert *tls.Certificate) ([]*x509.Certificate, crypto.PrivateKey)
TLSCertToX509 splits a TLS certificate into an x509 certificate chain and private key If the TLS cert does not contain a private key it is returned as nil.
This returns nil if the tls certificate doesn't hold any x509 certificates
func Verify ¶
Verify the signature of a message using this key's public key. This verifies using the SHA256 hash of the message. this requires a public key to be created or imported returns true if the signature is valid for the message
func VerifyCert ¶
VerifyCert verifies whether the given certificate is a valid certificate for client authentication This returns the certificate CN as the clientID
func WatchFile ¶
WatchFile is a resilient file watcher that handles file renames Special features:
- This debounces multiple quick changes before invoking the callback
- After the callback, resubscribe to the file to handle file renames that change the file inode path to watch handler to invoke on change
This returns the fsnotify watcher. Remove it when done.
func WriteError ¶
func WriteError(w http.ResponseWriter, err error, code int)
WriteError is a convenience function that logs and writes an error If the reply has an error then write a bad request with the error as payload If code is 0 then http.StatusBadRequest will be returned
func WriteReply ¶
func WriteReply( w http.ResponseWriter, handled bool, data any, err error)
WriteReply is a convenience function that serializes the data and writes it as a response, optionally reporting an error with code BadRequest.
If data is already serialized then use w.Write(data) instead ¶
when handled, this returns a 200 status code if no error is returned. handled is false means the request is in progress. This returns a 201. if an err is returned this returns a 400 bad request or 403 unauthorized error code the data can contain error details.
func X509CertFromPEM ¶
func X509CertFromPEM(certPem string) (cert *x509.Certificate, err error)
X509CertFromPEM converts the PEM format certificate chain to a X509 certificate If the pem contains a chain only the first is returned.
func X509CertToPEM ¶
func X509CertToPEM(cert *x509.Certificate) (certPem string)
X509CertToPEM converts the x509 certificate to PEM format
func X509CertToTLS ¶
func X509CertToTLS(cert *x509.Certificate, privKey crypto.PrivateKey) *tls.Certificate
X509CertToTLS creates a TLS certificate from a x509 certificate and private key
func X509ChainFromPEM ¶
func X509ChainFromPEM(certPem string) (chain []*x509.Certificate, err error)
X509ChainFromPEM converts the PEM format certificate chain to a X509 certificate chain
func X509ChainToPEM ¶
func X509ChainToPEM(chain []*x509.Certificate) (certStr string)
X509ChainToPEM converts the x509 certificate chain to PEM format
func X509ChainToTLS ¶
func X509ChainToTLS(chain []*x509.Certificate, privKey crypto.PrivateKey) *tls.Certificate
X509ChainToTLS combines a x509 certificate chain and private key into a TLS certificate
Types ¶
type AsyncReceiver ¶
type AsyncReceiver[T comparable] struct { // contains filtered or unexported fields }
AsyncReceiver is a simple helper for waiting on data that will be received asynchronously.
Usage is simple, call WaitForResponse with a timeout, and if a response is received asynchronously then call SetResponse.
func NewAsyncReceiver ¶
func NewAsyncReceiver[T comparable]() AsyncReceiver[T]
Create a new receiver of async messages. FIXME: this should take a context that can be cancelled.
func (*AsyncReceiver[T]) Cancel ¶
func (arx *AsyncReceiver[T]) Cancel(data T)
Cancel the channel. Use this instead of SetResponse if no response is avaialble.
func (*AsyncReceiver[T]) SetResponse ¶
func (arx *AsyncReceiver[T]) SetResponse(data T)
Write the answer to the channel
func (*AsyncReceiver[T]) WaitForResponse ¶
func (arx *AsyncReceiver[T]) WaitForResponse(timeout time.Duration) (T, error)
WaitForResponse waits for the response to be set or times out.
If timeout is 0 or negative, a default of 60 seconds is used.
Returns the data set by SetResponse, or an error on timeout or cancel.
type KeyType ¶
type KeyType string
func DetermineKeyType ¶
DetermineKeyType returns the type of key
func GetPublicKeyFromCert ¶
func GetPublicKeyFromCert(cert *x509.Certificate) (keyType KeyType, pubKey crypto.PublicKey)
GetPublicKeyFromCert extracts the public key from x509 certificate. Returns nil if certificate doesn't hold a public key. The key can be an ecdsa or ed25519 public key.