识别可用的 CA

https://blueprints.launchpad.net/barbican/+spec/identify-cas

问题描述

可能存在多个 CA 插件,每个插件可能与多个后端 CA 服务器通信。因此,需要一种机制来允许客户端选择后端 CA 服务器。

此外,Dogtag 计划实现配置轻量级子 CA 的能力——可以在同一 CA 实例中存在的下级 CA。这为为每个项目配置一个单独的 CA 实例打开了可能性,以便项目可以拥有仅限于该项目的证书。因此,还需要一种机制将项目与首选 CA 关联起来,以便如果客户端未请求特定的 CA,则选择首选 CA。

此外,应添加一种机制,允许客户端发现特定 Barbican 实例可用的 CA 服务器。

提议的变更

我们需要添加一个新的资源 CertificateAuthorities,它将指定 Barbican 可用的 CA。该资源将允许列出 CA 并将项目与 CA 关联。有关详细信息,请参阅 REST API 部分。

需要四个新表

  • CertificateAuthority,它将列出可用的 CA。此表将包括 Barbican 生成的 ca_id、插件名称、plugin_ca_id、有关 CA 的信息以及缓存到期时间。假设数据已过时,并且在缓存到期时间到期时需要刷新。

  • CertificateAuthorityMetadatum,它包含有关 CA 的数据,将提供给客户端。

  • ProjectCertificateAuthority,它将列出每个项目定义的 CA 集合。如果项目选择这样做,它可以指定一组 CA(由 ca_id 引用),特定项目可以使用这些 CA。为该项目添加的第一个条目将自动添加到该项目的 PrefCA 表中,以确保每个项目始终都有一个首选 CA。

  • PreferredCertificateAuthority (PrefCA),它包含每个项目的首选 CA 条目。此表需要 project_id 是唯一的,以便每个项目只有一个首选 CA。首选全局 CA 的特殊条目将具有“project_id”= 0。

有关详细信息,请参阅数据模型部分。

ProjectCertificateAuthority 表将通过 REST API 调用由项目管理员更新。

CertificateAuthority 表将按如下方式更新

  • 在启动时,Barbican 应遍历所有 CA 插件并执行 certificate_resources.update_ca_list(plugin_name)。这将触发对每个插件的 provides() 方法的调用。

  • provides() 调用将查询后端 CA 以确定提供的 CA。它将返回相关数据,即,根据需要填充/更新 CertificateAuthority 和 CertificateAuthorityMetadatum 表的列表/字典(plugin_ca_id、描述、ca_ski 等)。它还将返回数据的到期时间。

  • 然后,CA 和 CA 元数据表将由 Barbican 核心中定义的方法更新。(例如,certificate_resources.update_ca_list(plugin_name))。Barbican 核心将使用 plugin_ca_id 将 CA 条目映射到正确的 ca_id。此时:将添加新的 CA;将删除已停用的 CA;并将更新现有的 CA。在每种情况下,将更新到期时间。

  • 下面提供了一种方法,供用户获取可用 CA 的列表。如果 CA 的到期时间已过,则将通过调用 provides() 方法查询该特定 CA 的插件。CA 表和 CA 元数据表将相应地更新。

  • 如果发出证书请求并指定了 ca_id,则将在 CA 表中查找相关的插件。如果此 ca_id 的条目已过时,则将调用该 CA 的 provides() 方法以更新 CA 表。

请求证书时的逻辑

当请求证书时,

  • 如果提供了 ca_id

    • 如果 ca_id 未在 CA 表中定义,则返回 400 错误。

    • 如果项目在 PCA 表中存在任何条目,并且 ca_id 不是这些条目之一,则返回 403 错误。

    • 否则,请求将传递到 CA 表中条目指定的插件。

  • 如果未提供 ca_id

    • 如果在 PrefCA 表中存在至少一个项目的条目,则 barbican 核心将选择首选 CA,并将请求传递到该 CA。

    • 如果项目在 PrefCA 表中不存在条目,则将选择 prefCA 表中指定的全局首选 CA。如果没有定义首选 CA,则将选择第一个 CA 插件。

plugin_ca_id 将作为 order_metadata 的一部分传递给插件。

备选方案

无。

数据模型影响

将添加四个新表:CertificateAuthority(CA 表)、CertificateAuthorityMetadatum(CAM 表)、ProjectCertificateAuthority(PCA 表)和 PreferredCertificateAuthority(PrefCA 表)。

CA 表将具有以下字段
  • ca_id - Barbican 生成的 CA 的唯一标识符

  • plugin_name

  • plugin_ca_id - (字符串) 插件生成的 CA 的标识符。此标识符必须对插件是唯一的。

  • expiration_time

  • ca_metadata(见下文)

为了存储有关每个 CA 的元数据,数据将存储在 CertificateAuthorityMetadatum(CAM)表中。此表将包含以下字段

  • ca_id - CA 表的外键

  • value

将首先存储以下键值数据
  • name - 人类可读的名称

  • description

  • ca 签名证书

  • intermediates

关于 id 的说明

将呈现给客户端的 ca_id 将是 Barbican 生成的 ca_id。但是,由于可用的 CA 由后端 CA 确定,因此插件需要提供一个对插件唯一的 plugin_ca_id,以便可以将 plugin_ca_id 映射到 Barbican 生成的 ca_id。

PCA 表列出了为每个项目定义的 CA。每个项目可以有多个条目。它将具有以下字段

  • project_id

  • ca_id(CA 表的外键)

PrefCA 表列出了全局或任何特定项目的首选 CA。这是为了强制执行只能定义一个 CA 作为全局或预项目首选的规则。此表将具有以下字段

  • project_id – 需要是唯一的

  • ca_id – CA 表的外键

REST API 影响

我们需要一个新的资源来公开可用的 CA。此资源将允许以下操作

  • GET /cas - 列出所有可用的 CA。

  • GET /cas/{ca_id} - 获取由 ca_id 引用 CA 的详细信息。这将包括诸如指向 CA 信息的 HATEOAS 链接、名称和描述之类的内容。

  • GET /cas/{ca_id}/cacert - 获取 CA 的 PKCS7 格式的 base 64 编码的签名证书

  • GET /cas/{ca_id}/intermediates - 获取 CA 证书和中间证书的 base 64 编码的 PKCS7 格式。

  • GET /cas/{ca_id}/projects - 列出使用指定 ca_id 的 CA 的项目。仅限于全局管理员。这是一个允许全局管理员清理 PCA 表的操作,以防 CA 被停用。

  • POST /cas/{ca_id}/add-to-project - 在 PCA 表中添加 ca_id 的条目。project_id 由 authz 确定。仅限于项目管理员。如果这是添加到项目的第一个 CA,它将通过在 PrefCA 表中添加该项目的条目设置为首选。

  • POST /cas/{ca_id}/remove-from-project - 从 PCA 表中删除 ca_id 的条目。project_id 由 authz 确定。仅限于项目管理员。如果 CA 是项目的首选 CA,并且 PCA 表中不存在其他 CA,则还将删除 PrefCA 条目。如果 PCA 表中存在其他条目,则返回 400 错误。(“无法删除首选 CA。首先选择另一个项目 CA 作为首选。”)

  • POST /cas/{ca_id}/set-preferred - 将 ca_id 设置为项目的首选 CA。如果该 project_id/ca_id 没有 PCA 条目,则应返回 400 错误。仅限于项目管理员。

  • POST /cas/{ca_id}/set-global-preferred - 将 ca_id 设置为全局首选 CA。如果在请求中未指定 ca_id 并且项目没有 PCA 条目,则调用此 CA。仅限于全局管理员。

  • POST /cas/{ca_id}/unset-global-preferred - 取消将 ca_id 设置为全局首选 CA。仅限于全局管理员。

此外,证书的 Order 中将提供一个可选的元数据参数(ca_id),并如上所述进行处理。

安全影响

无。

通知与审计影响

无。

其他最终用户影响

python-barbicanclient 需要新的方法来检查 CA 列表并在请求时调用特定的 ca_id。

性能影响

此功能需要数据库访问才能在每次证书订单请求时获取 CA/项目/插件信息,这将对 API 和工作节点产生影响。

其他部署者影响

需要对已有的部署运行迁移脚本以添加新表。

开发人员影响

插件开发人员应编写一个返回正确信息的 provides() 方法。我们可以提供一个默认实现,该实现基于 plugin_name 创建 CA 表条目。

实现

负责人

主要负责人

alee-3 dave-mccowan

工作项

  • 添加新的数据模型(PCA、PrefCA、CA、CAM 表)

  • 向后端插件合同添加默认 provides() 调用。添加在启动时填充 CA 表的逻辑。

  • 添加 /cas 和相关的 REST API 调用以检索/设置这些资源。

  • 将 CA 选择逻辑添加到证书请求流程。

  • 添加每个插件特定的 provides() 方法。

依赖项

测试

当前的单元和功能测试也将修改以反映这些更改。

文档影响

这是一个需要记录的新功能。

参考资料