# 09. Ghostbusters Record（GBR）

## 9.1 对象定位

Ghostbusters Record（GBR）是一个可选的 RPKI Signed Object，用于承载“联系人信息”（人类可读的联系渠道），以便在证书过期、CRL 失效、密钥轮换等事件中能够联系到维护者。RFC 6493 §1。

GBR 由 CMS 外壳 + vCard 载荷组成：

- 外壳：RFC 6488（更新：RFC 9589）
- 载荷（payload）：RFC 6493 定义的 vCard profile（基于 RFC 6350 vCard 4.0 的严格子集）。RFC 6493 §5。

## 9.2 原始载体与编码

- 外壳：CMS SignedData DER（见 `05_signed_object_cms.md`）。RFC 6493 §6（引用 RFC 6488）。
- eContentType：`id-ct-rpkiGhostbusters`，OID `1.2.840.113549.1.9.16.1.35`。RFC 6493 §6；RFC 6493 §9.1。
- eContent：一个 OCTET STRING，其 octets 是 vCard 文本（vCard 4.0，且受 RFC 6493 的 profile 约束）。RFC 6493 §5；RFC 6493 §6。

> 说明：与 ROA/MFT 这类“eContent 内部再 DER 解码为 ASN.1 结构”的对象不同，GBR 的 eContent 语义上就是“vCard 文本内容本身”（由 Signed Object Template 的 `eContent OCTET STRING` 承载）。RFC 6493 §6。

## 9.3 vCard profile（RFC 6493 §5）

GBR 的 vCard payload 是 RFC 6350 vCard 4.0 的严格子集，仅允许以下属性（properties）：

- `BEGIN`：必须为第一行，值必须为 `BEGIN:VCARD`。RFC 6493 §5。
- `VERSION`：必须为第二行，值必须为 `VERSION:4.0`。RFC 6493 §5（引用 RFC 6350 §3.7.9）。
- `FN`：联系人姓名或角色名。RFC 6493 §5（引用 RFC 6350 §6.2.1）。
- `ORG`：组织信息（可选）。RFC 6493 §5（引用 RFC 6350 §6.6.4）。
- `ADR`：邮寄地址（可选）。RFC 6493 §5（引用 RFC 6350 §6.3）。
- `TEL`：语音/传真电话（可选）。RFC 6493 §5（引用 RFC 6350 §6.4.1）。
- `EMAIL`：邮箱（可选）。RFC 6493 §5（引用 RFC 6350 §6.4.2）。
- `END`：必须为最后一行，值必须为 `END:VCARD`。RFC 6493 §5。

额外约束：

- `BEGIN`、`VERSION`、`FN`、`END` 必须包含。RFC 6493 §5。
- 为保证可用性，`ADR`/`TEL`/`EMAIL` 三者中至少一个必须包含。RFC 6493 §5。
- 除上述属性外，**其他属性 MUST NOT** 出现。RFC 6493 §5。

## 9.4 解析规则（payload 语义层）

输入：`RpkiSignedObject`。

1) 解析 CMS 外壳，得到 `econtent_type` 与 `econtent_bytes`。RFC 6488 §3；RFC 9589 §4。  
2) 要求 `econtent_type == 1.2.840.113549.1.9.16.1.35`。RFC 6493 §6。  
3) 将 `econtent_bytes` 解析为 vCard 文本，并按 RFC 6493 §5 的 profile 校验（属性集合、必选项、行首/行尾约束）。RFC 6493 §5；RFC 6493 §7。  
4) 通过校验后，将允许属性映射为 `GhostbustersVCard` 语义对象（见下）。

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

### 9.5.1 `GhostbustersObject`

| 字段 | 类型 | 语义 | 约束/解析规则 | RFC 引用 |
|---|---|---|---|---|
| `signed_object` | `RpkiSignedObject` | CMS 外壳 | 外壳约束见 RFC 6488/9589 | RFC 6493 §6；RFC 6488 §3；RFC 9589 §4 |
| `econtent_type` | `Oid` | eContentType | 必须为 `1.2.840.113549.1.9.16.1.35` | RFC 6493 §6 |
| `vcard` | `GhostbustersVCard` | vCard 语义对象 | 由 eContent 文本解析并校验 profile | RFC 6493 §5；RFC 6493 §7 |

### 9.5.2 `GhostbustersVCard`（vCard 4.0 profile）

| 字段 | 类型 | 语义 | 约束/解析规则 | RFC 引用 |
|---|---|---|---|---|
| `raw_text` | `string` | 原始 vCard 文本 | 由 eContent bytes 解码得到；用于保留原文/诊断 | RFC 6493 §5-§7 |
| `fn` | `string` | 联系人姓名/角色名 | `FN` 必须存在 | RFC 6493 §5 |
| `org` | `optional[string]` | 组织 | `ORG` 可选 | RFC 6493 §5 |
| `adrs` | `list[string]` | 邮寄地址（原始 ADR value） | 允许 0..N；至少满足“ADR/TEL/EMAIL 至少一项存在” | RFC 6493 §5 |
| `tels` | `list[Uri]` | 电话 URI（从 TEL 提取的 `tel:` 等 URI） | 允许 0..N；至少满足“ADR/TEL/EMAIL 至少一项存在” | RFC 6493 §5 |
| `emails` | `list[string]` | 邮箱地址 | 允许 0..N；至少满足“ADR/TEL/EMAIL 至少一项存在” | RFC 6493 §5 |

> 说明：RFC 6493 并未要求 RP 必须完整解析 vCard 参数（例如 `TYPE=WORK`、`VALUE=uri`），因此此处将 `ADR`/`TEL`/`EMAIL` 建模为“足以联络”的最小语义集合；实现可在保留 `raw_text` 的同时按 RFC 6350 扩展解析能力。

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

- eContentType 必须为 `id-ct-rpkiGhostbusters`（OID `1.2.840.113549.1.9.16.1.35`），且该 OID 必须同时出现在 eContentType 与 signedAttrs.content-type。RFC 6493 §6（引用 RFC 6488）。
- eContent 必须是 vCard 4.0 文本，且必须满足 RFC 6493 §5 的 profile：
  - 第一行 `BEGIN:VCARD`；
  - 第二行 `VERSION:4.0`；
  - 末行 `END:VCARD`；
  - 必须包含 `FN`；
  - `ADR`/`TEL`/`EMAIL` 至少一个存在；
  - 除允许集合外不得出现其他属性。RFC 6493 §5；RFC 6493 §7。

## 9.7 与 EE 证书的语义约束（为后续验证准备）

GBR 使用 CMS 外壳内的 EE 证书验证签名。RFC 6493 对该 EE 证书提出一条资源扩展约束：

- 用于验证 GBR 的 EE 证书在描述 Internet Number Resources 时，必须使用 `inherit`，而不是显式资源集合。RFC 6493 §6（引用 RFC 3779）。

