72 lines
3.2 KiB
Go
72 lines
3.2 KiB
Go
package store
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"math"
|
||
)
|
||
|
||
var (
|
||
// ErrInvalidAuthKeyProtocolExpiry 表示新握手试图写入 migration-only
|
||
// unknown sentinel 或超出 TL int32 时间戳范围的协议寿命。
|
||
ErrInvalidAuthKeyProtocolExpiry = errors.New("invalid auth key protocol expiry")
|
||
// ErrAuthKeyProtocolMetadataConflict 表示同一 cryptographic auth_key_id
|
||
// 被尝试改写为另一 key body 或另一 permanent/temp 类型/寿命。
|
||
ErrAuthKeyProtocolMetadataConflict = errors.New("auth key protocol metadata conflict")
|
||
// ErrAuthKeyNotPermanent 防止 authorization 落到 temporary/legacy-unknown key。
|
||
ErrAuthKeyNotPermanent = errors.New("auth key is not permanent")
|
||
// ErrAuthKeyBindingInvalid 表示 temp/perm 引用缺失、类型错误,或 binding
|
||
// expiry 未归一到握手权威值。
|
||
ErrAuthKeyBindingInvalid = errors.New("invalid temporary auth key binding")
|
||
)
|
||
|
||
// ValidNewAuthKeyProtocolExpiry 只允许握手写 permanent(0) 或 TL int32
|
||
// 范围内的 positive temporary expiry。-1 仅能由 migration 0086 写入。
|
||
func ValidNewAuthKeyProtocolExpiry(expiresAt int) bool {
|
||
return expiresAt >= 0 && int64(expiresAt) <= math.MaxInt32
|
||
}
|
||
|
||
// AuthKeyData 是一条持久化的 MTProto auth key 记录。
|
||
//
|
||
// 不依赖 td 协议类型:连接层在边界做 crypto.AuthKey ↔ AuthKeyData 转换。
|
||
type AuthKeyData struct {
|
||
ID [8]byte // auth_key_id(key 的 SHA1 低 64 位)
|
||
Value [256]byte // 2048-bit auth key
|
||
ServerSalt int64 // 密钥交换产出的初始 server salt
|
||
CreatedAt int64 // unix 秒
|
||
// ExpiresAt 是 temporary/media-temporary auth key 的协议失效时间(unix 秒)。
|
||
// 0 只允许表示 permanent key;-1 仅表示 migration 0086 无法证明类型的历史 key,
|
||
// edge 必须用 -404 拒绝并迫使客户端重握手。key 类型是握手事实,不能由
|
||
// authorization 是否存在推断。
|
||
ExpiresAt int
|
||
Layer int
|
||
DeviceModel string
|
||
Platform string
|
||
SystemVersion string
|
||
APIID int
|
||
AppVersion string
|
||
// 用户绑定不在此处:auth_key 是协议产物,授权(auth_key↔user + 设备信息)由 authorization 承载(P2)。
|
||
}
|
||
|
||
type AuthKeyClientInfo struct {
|
||
Layer int
|
||
DeviceModel string
|
||
Platform string
|
||
SystemVersion string
|
||
APIID int
|
||
AppVersion string
|
||
}
|
||
|
||
// AuthKeyStore 持久化 auth key。实现见 store/memory(测试替身)、store/postgres。
|
||
type AuthKeyStore interface {
|
||
// Save 保存一条 auth key 记录;同 ID 重试只能保持 key body 与协议类型/寿命不变。
|
||
Save(ctx context.Context, k AuthKeyData) error
|
||
// Get 按 auth_key_id 查询;不存在时 found=false。
|
||
Get(ctx context.Context, id [8]byte) (data AuthKeyData, found bool, err error)
|
||
// UpdateClientInfo 合并更新 auth key 的客户端协商元数据。
|
||
// 空字段不覆盖已有值,layer/api_id 为 0 时不覆盖。
|
||
UpdateClientInfo(ctx context.Context, id [8]byte, info AuthKeyClientInfo) error
|
||
// Delete 删除一条 auth key 记录(destroy_auth_key)。不存在时静默成功。
|
||
// 连接层每帧按 auth_key_id 回查本接口,删除后该 key 的入站帧立即失效。
|
||
Delete(ctx context.Context, id [8]byte) error
|
||
}
|