# 01. TAL（Trust Anchor Locator）

## 1.1 对象定位

TAL（Trust Anchor Locator）用于向 RP 提供：

1) 可检索“当前 TA 证书”的一个或多个 URI；以及  
2) 该 TA 证书的 `subjectPublicKeyInfo`（SPKI）期望值（用于绑定/防替换）。

RFC 8630 §2；RFC 8630 §2.3。

## 1.2 原始载体与编码

- 载体：文本文件（ASCII/UTF-8 兼容的行文本）。
- 行结束：允许 `CRLF` 或 `LF`。RFC 8630 §2.2。
- 结构：`[可选注释区] + URI 区 + 空行 + Base64(SPKI DER)`。RFC 8630 §2.2。

### 1.2.1 注释区

- 一行或多行，以 `#` 开头，后随人类可读 UTF-8 文本。RFC 8630 §2.2。
- 注释行文本需符合 RFC 5198 §2 的限制（RFC 8630 §2.2 引用）。

### 1.2.2 URI 区

- 一行或多行，每行一个 TA URI，按序排列。RFC 8630 §2.2。
- TA URI **MUST** 是 `rsync` 或 `https`。RFC 8630 §2.2。

### 1.2.3 空行分隔

- URI 区后必须有一个额外的换行（即空行），用于与 Base64 区分隔。RFC 8630 §2.2（第 3 点）。

### 1.2.4 SPKI（Base64）

- `subjectPublicKeyInfo` 以 DER 编码（ASN.1）后，再 Base64 编码表示。RFC 8630 §2.2（第 4 点）。
- 为避免长行，Base64 字符串中 **MAY** 插入换行。RFC 8630 §2.2。
- SPKI ASN.1 类型来自 X.509 / RFC 5280。RFC 8630 §2.2（第 4 点）；RFC 5280 §4.1.2.7。

#### 1.2.4.1 `SubjectPublicKeyInfo` 的 ASN.1 定义（RFC 5280 §4.1）

TAL 中携带的是一个 X.509 `SubjectPublicKeyInfo` 的 DER 字节串（再 Base64）。其 ASN.1 定义如下：RFC 5280 §4.1。

```asn1
SubjectPublicKeyInfo  ::=  SEQUENCE  {
     algorithm            AlgorithmIdentifier,
     subjectPublicKey     BIT STRING  }
```

其中 `algorithm`/`subjectPublicKey` 的取值受 RPKI 算法 profile 约束（例如 RSA 2048 + SHA-256 等；SKI/AKI 计算仍用 SHA-1）。RFC 5280 §4.1.2.7；RFC 7935 §2-§3.1；RFC 6487 §4.8.2-§4.8.3。

## 1.3 解析规则（语义层）

输入：`TalFileBytes: bytes`。

解析步骤：

1) 按 `LF` / `CRLF` 识别行。RFC 8630 §2.2。  
2) 从文件开头读取所有以 `#` 开头的行，作为 `comments`（保留去掉 `#` 后的 UTF-8 文本或保留原始行均可，但需保持 UTF-8）。RFC 8630 §2.2。  
3) 继续读取一行或多行非空行，作为 `ta_uris`（保持顺序）。RFC 8630 §2.2（第 2 点）。  
4) 读取一个空行（必须存在）。RFC 8630 §2.2（第 3 点）。  
5) 将剩余行拼接为 Base64 文本（移除行分隔），Base64 解码得到 `subject_public_key_info_der`。RFC 8630 §2.2（第 4 点）。  
6) 可选：将 `subject_public_key_info_der` 解析为 X.509 `SubjectPublicKeyInfo` 结构（用于与 TA 证书比对）。RFC 8630 §2.3；RFC 5280 §4.1.2.7。

URI 解析与约束：

- `ta_uris[*]` 的 scheme **MUST** 为 `rsync` 或 `https`。RFC 8630 §2.2。
- 每个 `ta_uri` **MUST** 指向“单个对象”，且 **MUST NOT** 指向目录或集合。RFC 8630 §2.3。

## 1.4 抽象数据模型（接口）

### 1.4.1 `Tal`

| 字段 | 类型 | 语义 | 约束/解析规则 | RFC 引用 |
|---|---|---|---|---|
| `raw` | `bytes` | TAL 原始文件字节 | 原样保留（可选但建议） | RFC 8630 §2.2 |
| `comments` | `list[Utf8Text]` | 注释行（按出现顺序） | 每行以 `#` 开头；文本为 UTF-8；内容限制见 RFC 5198 §2 | RFC 8630 §2.2 |
| `ta_uris` | `list[Uri]` | TA 证书位置列表 | 至少 1 个；按序；每个 scheme 必须是 `rsync` 或 `https` | RFC 8630 §2.2 |
| `subject_public_key_info_der` | `DerBytes` | TA 证书 SPKI 的期望 DER | Base64 解码所得 DER；Base64 中可有换行 | RFC 8630 §2.2 |

### 1.4.2 `TaUri`（可选细化）

> 若你的实现希望对 URI 做更强类型化，可在 `Tal.ta_uris` 上进一步拆分为 `TaUri` 结构。

| 字段 | 类型 | 语义 | 约束/解析规则 | RFC 引用 |
|---|---|---|---|---|
| `uri` | `Uri` | 完整 URI 文本 | scheme 为 `rsync` 或 `https` | RFC 8630 §2.2 |
| `scheme` | `enum` | `rsync` / `https` | 从 `uri` 解析 | RFC 8630 §2.2 |

## 1.5 字段级约束清单（实现对照）

- TAL 由（可选）注释区 + URI 区 + 空行 + Base64(SPKI DER) 组成。RFC 8630 §2.2。
- URI 区至少 1 行，每行一个 TA URI，顺序有意义。RFC 8630 §2.2。
- TA URI 仅允许 `rsync` 或 `https`。RFC 8630 §2.2。
- Base64 区允许插入换行。RFC 8630 §2.2。
- 每个 TA URI 必须引用单个对象，不能指向目录/集合。RFC 8630 §2.3。
