【问题标题】:How use openssl to verify a certificate in PEM with a local trust store?如何使用 openssl 通过本地信任库验证 PEM 中的证书?
【发布时间】:2018-08-28 10:00:36
【问题描述】:

我有一个 PEM 格式的证书。假设我有一个从 google.com 复制的证书。

所以,链条就是

Google 信任服务-GlobalSign 根 CA-R2

->Google 互联网管理局 G3

-->*.google.com

假设我有证书*.google.com,并且我想要一个 C 程序用我在 Linux 中的本地信任存储来验证这个证书。比如说/etc/ssl/certs

我需要离线而不连接到服务器。我应该怎么办?

【问题讨论】:

    标签: c openssl certificate x509certificate x509


    【解决方案1】:

    围绕这个主题的整体 OpenSSL 文档相当有限,并且到处都有断开的链接,所以我的方法可能不是唯一的一种或最好的一种。据我所知,验证证书(链)是通过以下步骤完成的,以相反的顺序展开,因为我认为这样可以更好地理解。对于生成的代码,请参阅此答案的结尾。为简洁起见,所有代码都省略了错误检查。此外,没有解释证书吊销列表 (CRL) 的加载,我认为这超出了您的问题范围。

    实际验证功能

    验证证书(链)的功能由 OpenSSL 函数 X509_verify_cert() 提供。返回值1 表示验证成功,0 表示不成功。正如您在文档中看到的那样,该函数只需要一个X509_STORE_CTX 类型的参数,这是一个包含X509 证书集合的“上下文”(OpenSSL,IMO 中一个相当模糊和过度使用的术语)的结构参与。

    设置证书存储上下文

    证书存储上下文包含有关受信任证书、不受信任的中间证书和要验证的证书的信息。它的构造和初始化如下:

    store_ctx = X509_STORE_CTX_new();
    X509_STORE_CTX_init(store_ctx, store, cert, intermediates)
    

    store 参数将用于包含有关受信任证书的信息,cert 参数包含要验证的证书,而intermediates 参数是一堆不受信任的中间证书。

    store 参数

    X509_STORE 类型能够包含一组 X509 证书,并且为了验证证书需要提供有关受信任证书的信息。由于您在/etc/ssl/certs 中表明您拥有受信任的证书,因此可以按如下方式进行:

    store = X509_STORE_new();
    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
    X509_LOOKUP_add_dir(lookup, "/etc/ssl/certs", X509_FILETYPE_PEM);
    

    这假设您的本地信任存储已正确设置

    cert 参数`

    此参数包含要验证的实际证书。它可以通过多种方式从文件中加载,一种方法如下:

    bio_in = BIO_new_file(certFileName, "r");
    result = PEM_read_bio_X509(bio_in, NULL, NULL, NULL);
    BIO_free(bio_in);
    

    intermediates 参数

    OpenSSL 提供了一个stack API 来处理对象集合。 intermediates 参数是一组 X509 对象,其中包含要测试的证书和受信任证书之间的中间证书。在伪代码中可以填写如下:

    intermediates = sk_X509_new_null();
    for (filename in certFilenames) do {
        icert = readCert(filename);
        sk_X509_push(intermediates, icert);
    }
    

    解释到此结束,这应该为您提供验证链所需的一切。

    **关于下载链末尾的证书

    下载链末尾的证书通常包含在您的本地信任存储中。一些实验表明,您实际上可以将其输入验证函数,就好像它是一个不受信任的中间体一样,或者您可以省略它。两者似乎都以经过适当验证的链条结束。

    代码示例

    最后:-)

    #include <openssl/x509.h>
    #include <openssl/x509_vfy.h>
    #include <openssl/pem.h>
    
    const char *trustedCertsPath = "/etc/ssl/certs";
    
    int main(
        int argc,
        char **argv)
    {
        X509 *cert = NULL;
        X509 *icert = NULL;
        STACK_OF(X509) *intermediates = NULL;
        X509_STORE *store = NULL;
        X509_LOOKUP *lookup = NULL;
        X509_STORE_CTX *store_ctx = NULL;
        BIO *bio_in = NULL;
        int currentArg = 1;
        int result = 0;
    
        store = X509_STORE_new();
        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
        X509_LOOKUP_add_dir(lookup, trustedCertsPath, X509_FILETYPE_PEM);
    
        /* Certificate to be checked */
        bio_in = BIO_new_file(argv[currentArg++], "r");
        cert = PEM_read_bio_X509(bio_in, NULL, NULL, NULL);
        BIO_free(bio_in);
    
        /* Stack of untrusted intermediate certificates */
        intermediates = sk_X509_new_null();
        while (currentArg < argc) {
            bio_in = BIO_new_file(argv[currentArg++], "r");
            icert = PEM_read_bio_X509(bio_in, NULL, NULL, NULL);
            BIO_free(bio_in);
            sk_X509_push(intermediates, icert);
        }
    
        store_ctx = X509_STORE_CTX_new();
        X509_STORE_CTX_init(store_ctx, store, cert, intermediates);
    
        result = X509_verify_cert(store_ctx);
        printf("Result from X509_verify_cert is %d\n", result);
    
        sk_X509_pop_free(intermediates, X509_free);
        X509_STORE_CTX_cleanup(store_ctx);
        X509_STORE_CTX_free(store_ctx);
        X509_STORE_free(store);
    }
    

    您可以按如下方式构建和运行它(.pem 参数是包含您的证书和 PEM 格式的中间体的文件的名称:

    $ gcc  main.c $(pkg-config openssl --libs) -o verify -Wall
    $ ./verify \*.google.com.pem Google\ Internet\ Authority\ G3.pem
    Result from X509_verify_cert is 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-08
      • 2018-12-28
      • 1970-01-01
      • 2020-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多