Fingerprint hashes the raw key bytes rather than the hex string, so the same key written in different cases fingerprints identically.
58 lines
1.8 KiB
Go
58 lines
1.8 KiB
Go
// Package backup dumps and restores a whole Vantage MongoDB database.
|
|
//
|
|
// The archive never contains KEY_ENCRYPTION_KEY. It contains a fingerprint of
|
|
// it, which is enough to answer "will this archive restore into this
|
|
// deployment" and is not a hint at the value.
|
|
package backup
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"gitea.hostxtra.co.uk/mrhid6/vantage/shared/cryptobox"
|
|
)
|
|
|
|
// ErrNoKey is returned when no key was supplied at all. It is distinct from
|
|
// ErrBadKey because the operator remedies are different: one is "set the
|
|
// variable", the other is "the value you set is wrong".
|
|
var ErrNoKey = errors.New("KEY_ENCRYPTION_KEY is not set")
|
|
|
|
// ErrBadKey is returned when a key was supplied but is not 64 hex characters.
|
|
var ErrBadKey = errors.New("KEY_ENCRYPTION_KEY must be a 64-character hex string (32 bytes)")
|
|
|
|
// ParseKey decodes the hex form used by KEY_ENCRYPTION_KEY.
|
|
func ParseKey(hexKey string) ([]byte, error) {
|
|
if hexKey == "" {
|
|
return nil, ErrNoKey
|
|
}
|
|
key, err := hex.DecodeString(hexKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("%w: not hexadecimal", ErrBadKey)
|
|
}
|
|
if len(key) != cryptobox.KeySize {
|
|
return nil, fmt.Errorf("%w: decoded to %d bytes", ErrBadKey, len(key))
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
// Fingerprint is the SHA-256 of the raw key bytes, hex encoded.
|
|
//
|
|
// Of the raw bytes rather than of the hex string, so an operator who writes the
|
|
// key in uppercase in one deployment and lowercase in another still gets one
|
|
// fingerprint for one key.
|
|
func Fingerprint(key []byte) string {
|
|
sum := sha256.Sum256(key)
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
// FingerprintHex parses and fingerprints in one step.
|
|
func FingerprintHex(hexKey string) (string, error) {
|
|
key, err := ParseKey(hexKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return Fingerprint(key), nil
|
|
}
|