package webingress import ( "crypto/ed25519" "encoding/base64" "encoding/json" "fmt" "strings" ) type TrustedKeyConfig struct { KeyID string `json:"key_id"` PublicKey string `json:"public_key"` } func ParseTrustedKeysJSON(value string) (StaticEnvelopeKeyResolver, error) { value = strings.TrimSpace(value) if value == "" { return nil, nil } resolver := StaticEnvelopeKeyResolver{} var byID map[string]string if err := json.Unmarshal([]byte(value), &byID); err == nil && len(byID) > 0 { for keyID, publicKeyB64 := range byID { if err := resolver.addBase64(keyID, publicKeyB64); err != nil { return nil, err } } return resolver, nil } var list []TrustedKeyConfig if err := json.Unmarshal([]byte(value), &list); err != nil { return nil, fmt.Errorf("%w: trusted keys json must be object or array", ErrFabricEnvelopeSignatureInvalid) } for _, item := range list { if err := resolver.addBase64(item.KeyID, item.PublicKey); err != nil { return nil, err } } return resolver, nil } func (r StaticEnvelopeKeyResolver) addBase64(keyID string, publicKeyB64 string) error { keyID = strings.TrimSpace(keyID) if keyID == "" { return fmt.Errorf("%w: trusted key id required", ErrFabricEnvelopeSignatureInvalid) } decoded, err := decodeEnvelopeBase64(strings.TrimSpace(publicKeyB64)) if err != nil { return fmt.Errorf("%w: trusted public key must be base64 encoded", ErrFabricEnvelopeSignatureInvalid) } if len(decoded) != ed25519.PublicKeySize { return fmt.Errorf("%w: trusted public key must decode to %d bytes", ErrFabricEnvelopeSignatureInvalid, ed25519.PublicKeySize) } r[keyID] = append(ed25519.PublicKey(nil), decoded...) return nil } func TrustedKeysJSONForPublicKey(keyID string, publicKey ed25519.PublicKey) string { payload, _ := json.Marshal(map[string]string{ strings.TrimSpace(keyID): base64.StdEncoding.EncodeToString(publicKey), }) return string(payload) }