c - OpenSSL C 程序在 PKCS7_sign 函数上变得无响应

标签 c openssl ssl-certificate pkcs#7

我正在尝试运行以下代码来签署自制证书,但程序在以下代码段变得无响应。它不会崩溃或发生任何事情,但光标只是在那里闪烁。

if (sign) {
            if (!(pkcs7 = PKCS7_sign (cert, pkey, chain, in, 0))) { <----Here seems to be the problem
                fprintf (stderr, "Error making the PKCS#7 object\n");
                goto err;
            }
}

从调试来看,所有的变量似乎都有值,除了 chain,gdb 打印出来:

(gdb) p *chain
Cannot access memory at address 0x0

完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rand.h>

/*
* This code appearing before the main function is all for X509_STORE setup.
*/

/* these are defintions to make the example simpler */
#define CA_FILE "CAfile.pem"
#define CA_DIR "/etc/ssl"
#define CRL_FILE "CRLfile.pem"

int
verify_callback (int ok, X509_STORE_CTX * stor)
{
    if (!ok)
        fprintf (stderr, "Error: %s\n",
                 X509_verify_cert_error_string (stor->error));
    return ok;
}

X509_STORE *
create_store (void)
{
    X509_STORE *store;
    X509_LOOKUP *lookup;

    /* create the cert store and set the verify callback */
    if (!(store = X509_STORE_new ())) {
        fprintf (stderr, "Error creating X509_STORE_CTX object\n");
        goto err;
    }
    X509_STORE_set_verify_cb_func (store, verify_callback);

    /* load the CA certificates and CRLs */
    if (X509_STORE_load_locations (store, CA_FILE, CA_DIR) != 1) {
        fprintf (stderr, "Error loading the CA file or directory\n");
        goto err;
    }

    if (X509_STORE_set_default_paths (store) != 1) {
        fprintf (stderr, "Error loading the system-wide CA certificates\n");
        goto err;
    }

    if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()))) {
        fprintf (stderr, "Error creating X509_LOOKUP object\n");
        goto err;
    }

    if (X509_load_crl_file (lookup, CRL_FILE, X509_FILETYPE_PEM) != 1) {
        fprintf (stderr, "Error reading the CRL file\n");
        goto err;
    }

    /* set the flags of the store so that CRLs are consulted */
    X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK |
                          X509_V_FLAG_CRL_CHECK_ALL);
    return store;

err:
    return NULL;
}

int
main (int argc, char *argv[])
{
    int sign;
    X509 *cert;
    EVP_PKEY *pkey;
    STACK_OF (X509) * chain = NULL;
    X509_STORE *store;
    PKCS7 *pkcs7;
    FILE *fp;
    BIO *in, *out, *pkcs7_bio;

    OpenSSL_add_all_algorithms ();
    ERR_load_crypto_strings ();
    /*seed_prng ();*/ /*seed_prng(1024);Borked DOONT LEAVE OUT*/


    --argc, ++argv;
    if (argc < 2) {
        fprintf (stderr,
                 "Usage: sv (sign|verify) [privkey.pem] cert.pem ...\n");
        goto err;
    }
    if (!strcmp (*argv, "sign"))
        sign = 1;
    else if (!strcmp (*argv, "verify"))
        sign = 0;
    else {
        fprintf (stderr,
                 "Usage: sv (sign|verify) [privkey.pem] cert.pem ...\n");
        goto err;
    }
    --argc, ++argv;

    /* setup the BIO objects for stdin and stdout */
    if (!(in = BIO_new_fp (stdin, BIO_NOCLOSE)) ||
            !(out = BIO_new_fp (stdout, BIO_NOCLOSE))) {
        fprintf (stderr, "Error creating BIO objects\n");
        goto err;
    }
    if (sign) {

        /* read the signer private key */
        if (!(fp = fopen (*argv, "r")) ||
                !(pkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL))) {
            fprintf (stderr, "Error reading signer private key in %s\n", *argv);
            goto err;
        }
        fclose (fp);
        --argc, ++argv;
    } else {
        /* create the cert store and set the verify callback */
        if (!(store = create_store ()))
            fprintf (stderr, "Error setting up X509_STORE object\n");
    }

    /* read the signer certificate */
    if (!(fp = fopen (*argv, "r")) ||
            !(cert = PEM_read_X509 (fp, NULL, NULL, NULL))) {
        ERR_print_errors_fp (stderr);
        fprintf (stderr, "Error reading signer certificate in %s\n", *argv);
        goto err;
    }
    fclose (fp);
    --argc, ++argv;

    if (argc)
        chain = sk_X509_new_null ();
    while (argc) {
        X509 *tmp;

        if (!(fp = fopen (*argv, "r")) ||!(tmp = PEM_read_X509 (fp, NULL, NULL, NULL))) {
            fprintf (stderr, "Error reading chain certificate in %s\n", *argv);
            goto err;
        }
        sk_X509_push (chain, tmp);
        fclose (fp);
        --argc, ++argv;
    }

    if (sign) {
        if (!(pkcs7 = PKCS7_sign (cert, pkey, chain, in, 0))) {
            fprintf (stderr, "Error making the PKCS#7 object\n");
            goto err;
        }
        if (SMIME_write_PKCS7 (out, pkcs7, in, 0) != 1) {
            fprintf (stderr, "Error writing the S/MIME data\n");
            goto err;
        }
    } else {            /* verify */
        if (!(pkcs7 = SMIME_read_PKCS7 (in, &pkcs7_bio))) {
            fprintf (stderr, "Error reading PKCS#7 object\n");
            goto err;
        }
        if (PKCS7_verify (pkcs7, chain, store, pkcs7_bio, out, 0) != 1) {
            fprintf (stderr, "Error writing PKCS#7 object\n");
            goto err;
        } else
            fprintf (stdout, "Certifiate and Signature verified!\n");
    }

    return 0;
err:
    return -1;
}

如果有人有任何想法,我将不胜感激!

最佳答案

刚收到!阅读here

"In OpenSSL 1.0.0 the certs, signcert and pkey parameters can all be NULL if the PKCS7_PARTIAL flag is set."

将代码更改为:

if (sign) {
    if (!(pkcs7 = PKCS7_sign (cert, pkey, chain, in, PKCS7_PARTIAL))) {
        fprintf (stderr, "Error making the PKCS#7 object\n");
        goto err;
    }
}

一切都很好!

关于c - OpenSSL C 程序在 PKCS7_sign 函数上变得无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18915964/

相关文章:

ssl-certificate - OB 证书和 eIDAS 有什么区别?

c - C 中关系运算符的前缀与后缀。运算符结合性如何影响?

c - 第二次读取内核会覆盖第一次实例

c - 为什么编写这个程序会输出奇怪的字符串?

android - 在 Android 中升级 OpenSSL

azure - SSL错误: HTTPSConnectionPool when registering ML model on Azure

java - 如何使用 JNI 将终端输出从 C 程序重定向到 System.out?

c - 如何将 ECDSA SIG 签名转换为 C 中的字符数组

python - SSL错误 : sslv3 alert handshake failure

java - 使用客户端证书和 Android 的 HttpsURLConnection 通过 SSL 上传文件