如何枚举捆绑包中的多个证书?

How to enumerate through multiple certificates in a bundle?

我可以从包含证书的文件中创建 OpenSSL::X509::Certificate 个对象:

blob = IO.binread path
cert = OpenSSL::X509::Certificate.new blob

但是,这会根据在文件中找到的第一个 证书创建证书对象。在处理 certificate-bundles 时,同一文件中的后续证书会被悄悄忽略。

我想,我可以在 "\n-----END CERTIFICATE-----\n" 上拆分 blob,然后将每个部分提供给 OpenSSL::X509::Certificate.new,但我不确定,这是否适用于所有文件格式,我的脚本可能会遇到并期望在其上运行。

有没有更好的方法?

做了一些挖掘,似乎 Ruby openssl 绑定不支持这个。这似乎也不是使用原始 C 绑定的常见 and/or 容易做到的事情。我可以在网上找到的所有代码都显示使用单个证书执行操作,或使用 X509 存储来验证其他证书。我还没有看到任何使用单个证书 "object" 引用多个证书,and/or 在商店中迭代证书的示例。

所以我认为简短的回答是:不。至少 Ruby 绑定提供的任何东西都无法帮助您做到这一点。

如果您的用例是根据一捆证书验证证书,总是有 OpenSSL::X509::Store,它有一个方法 store.add_file 可以将该文件中的所有证书添加到存储中,并且有根据包内容验证证书是否有效的方法。

好的,假设只有 PEM 编码的证书可以打包到一个包中,我编写了如下代码。如果假设无效——或者如果您能提供更好的方法,请告诉我!

DELIMITER = "\n-----END CERTIFICATE-----\n"
blob = IO.binread path
blobs = blob.split(DELIMITER)
blobs.each do |blob|
    blob += DELIMITER # Does not break DER
    cert = OpenSSL::X509::Certificate.new blob
    .... process the cert ....
end

可以使用 scan 而不是拆分然后重新添加定界符,但这需要使用正则表达式,这可能比我正在做的更昂贵...

此代码也适用于 DER 编码的证书 -- 但每个文件只能使用一个,因为没有明显的方法来拆分它们。

我不知道 ruby,但是使用 C 可以像

一样加载 CRT(和 CRL)包
X509_STORE  *store = X509_STORE_new();
X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());

X509_LOOKUP_load_file(lookup, argv[i], X509_LU_X509);

并使用

迭代它的元素
for (int i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
    X509_OBJECT *o = sk_X509_OBJECT_value(store->objs, i);

    switch (o->type) {
    case X509_LU_X509:
        handle_crt(o->data.x509);