package licence import ( "bytes" "crypto/ed25519" "encoding/json" "fmt" "unicode/utf8" ) type SigningKeyCertificate struct { FormatVersion int `json:"format_version"` KeyID string `json:"key_id"` PublicKey string `json:"public_key"` RootSignature string `json:"root_signature"` } type Envelope struct { FormatVersion int `json:"format_version"` Licence Claims `json:"licence"` SigningKeyCertificate SigningKeyCertificate `json:"signing_key_certificate"` Signature string `json:"signature"` } func Parse(content []byte) (Envelope, error) { var envelope Envelope if len(content) > maximumLicenceFileBytes { return envelope, ErrFileTooLarge } if err := strictDecodeJSON(content, &envelope); err != nil { return envelope, fmt.Errorf("%w: %v", ErrMalformedFile, err) } if err := validateEnvelopeFormat(envelope); err != nil { return envelope, err } return envelope, nil } func MarshalEnvelope(envelope Envelope) ([]byte, error) { if err := validateEnvelopeFormat(envelope); err != nil { return nil, err } var output bytes.Buffer encoder := json.NewEncoder(&output) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") if err := encoder.Encode(envelope); err != nil { return nil, fmt.Errorf("编码许可证文件: %w", err) } if output.Len() > maximumLicenceFileBytes { return nil, ErrFileTooLarge } return output.Bytes(), nil } func RootPublicKey() ed25519.PublicKey { publicKey := make(ed25519.PublicKey, len(rootPublicKey)) copy(publicKey, rootPublicKey[:]) return publicKey } func VerifySigningKeyCertificate(c SigningKeyCertificate) (ed25519.PublicKey, error) { if c.FormatVersion != formatVersion { return nil, fmt.Errorf("%w: 格式版本错误", ErrInvalidKeyCertificate) } if _, err := parseUUID(c.KeyID); err != nil { return nil, fmt.Errorf("%w: 密钥 ID 格式错误", ErrInvalidKeyCertificate) } publicKey, err := decodeBase64URL(c.PublicKey, ed25519.PublicKeySize) if err != nil { return nil, fmt.Errorf("%w: 公钥格式错误", ErrInvalidKeyCertificate) } rootSignature, err := decodeBase64URL(c.RootSignature, ed25519.SignatureSize) if err != nil { return nil, fmt.Errorf("%w: 根签名格式错误", ErrInvalidKeyCertificate) } message, err := CertificateMessage(c) if err != nil { return nil, fmt.Errorf("%w: 凭证消息格式错误", ErrInvalidKeyCertificate) } if !ed25519.Verify(rootPublicKey[:], message, rootSignature) { return nil, fmt.Errorf("%w: 根签名验证失败", ErrInvalidKeyCertificate) } result := make(ed25519.PublicKey, len(publicKey)) copy(result, publicKey) return result, nil } func validateEnvelopeFormat(envelope Envelope) error { if envelope.FormatVersion != formatVersion || envelope.SigningKeyCertificate.FormatVersion != formatVersion { return ErrUnsupportedVersion } if _, err := parseUUID(envelope.Licence.ID); err != nil { return fmt.Errorf("%w: 许可证 ID 格式错误", ErrMalformedFile) } if _, err := parseUUID(envelope.Licence.SigningKeyID); err != nil { return fmt.Errorf("%w: 签发密钥 ID 格式错误", ErrMalformedFile) } if _, err := parseUUID(envelope.SigningKeyCertificate.KeyID); err != nil { return fmt.Errorf("%w: 凭证密钥 ID 格式错误", ErrMalformedFile) } if !utf8.ValidString(envelope.Licence.PlatformName) || !utf8.ValidString(envelope.Licence.Workspace) { return fmt.Errorf("%w: 主体字符串不是有效的 UTF-8", ErrMalformedFile) } if _, err := envelope.Licence.IssuedOn.Time(); err != nil { return fmt.Errorf("%w: 签发日期格式错误", ErrMalformedFile) } if _, err := envelope.Licence.ValidFrom.Time(); err != nil { return fmt.Errorf("%w: 生效日期格式错误", ErrMalformedFile) } if _, err := envelope.Licence.ExpiresOn.Time(); err != nil { return fmt.Errorf("%w: 到期日期格式错误", ErrMalformedFile) } if _, err := decodeBase64URL(envelope.SigningKeyCertificate.PublicKey, ed25519.PublicKeySize); err != nil { return fmt.Errorf("%w: 凭证公钥格式错误", ErrMalformedFile) } if _, err := decodeBase64URL(envelope.SigningKeyCertificate.RootSignature, ed25519.SignatureSize); err != nil { return fmt.Errorf("%w: 根签名格式错误", ErrMalformedFile) } if _, err := decodeBase64URL(envelope.Signature, ed25519.SignatureSize); err != nil { return fmt.Errorf("%w: 许可证签名格式错误", ErrMalformedFile) } return nil }