48 lines
1.3 KiB
Go
48 lines
1.3 KiB
Go
package audit
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
type keyDocument struct {
|
|
Version int `json:"version"`
|
|
Keys []struct {
|
|
KeyID string `json:"key_id"`
|
|
Secret string `json:"secret_base64url"`
|
|
} `json:"keys"`
|
|
}
|
|
|
|
func LoadKeys(path string) (map[string][]byte, error) {
|
|
raw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, errors.New("read Bell audit key file")
|
|
}
|
|
var document keyDocument
|
|
decoder := json.NewDecoder(bytes.NewReader(raw))
|
|
decoder.DisallowUnknownFields()
|
|
if err := decoder.Decode(&document); err != nil || document.Version != 1 || len(document.Keys) == 0 {
|
|
return nil, errors.New("invalid Bell audit key file")
|
|
}
|
|
var trailing any
|
|
if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) {
|
|
return nil, errors.New("invalid Bell audit key file")
|
|
}
|
|
values := make(map[string][]byte, len(document.Keys))
|
|
for _, item := range document.Keys {
|
|
secret, err := base64.RawURLEncoding.DecodeString(item.Secret)
|
|
if err != nil || !keyIDPattern.MatchString(item.KeyID) || len(secret) < 32 {
|
|
return nil, errors.New("invalid Bell audit key")
|
|
}
|
|
if _, exists := values[item.KeyID]; exists {
|
|
return nil, errors.New("duplicate Bell audit key ID")
|
|
}
|
|
values[item.KeyID] = secret
|
|
}
|
|
return values, nil
|
|
}
|