创建具有专有名称字段的自签名证书

标签 c ssl openssl self-signed csr

我正在尝试编写一个应用程序,它将创建一个带有提供的专有名称的自签名证书。

我有以下创建 .key 和 .csr 文件的应用程序。

#include <stdio.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>

#define _RAND_FILENAME  "/dev/random"
#define _RAND_LOADSIZE  128
#define _RSA_KEYSIZE    1024


int build_and_save_csr(int dn_entries, char *dn_fields[], char *dn_values[], FILE *req_f, FILE *priv_f)
{
    X509_REQ    *req_p;
    EVP_PKEY    *key_p;
    RSA     *rsa_p;
    X509_NAME   *name_p = NULL;
    int     priv_len;
    unsigned char   *priv_p;
    int     i;

    if (!(req_p = X509_REQ_new())) {
        fprintf(stderr, "X509_REQ_new() failed\n");
        return -1;
    }

    if (!(key_p = EVP_PKEY_new())) {
        X509_REQ_free(req_p);
        fprintf(stderr, "EVP_PKEY_new() failed\n");
        return -1;
    }

#if 0
    if (RAND_load_file(_RAND_FILENAME, _RAND_LOADSIZE) != _RAND_LOADSIZE) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "RAND_load_file() failed\n");
        return -1;
    }
#endif

    if (!(rsa_p = RSA_generate_key(_RSA_KEYSIZE, RSA_F4, NULL, NULL))) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "RSA key generatione failed\n");
        return -1;
    }

    if (!EVP_PKEY_assign_RSA(key_p, rsa_p)) {
        X509_REQ_free(req_p);
        RSA_free(rsa_p);
        EVP_PKEY_free(key_p);
        return -1;
    }
    /*!!! the memory for rsa_p is now managed by key_p - don't free! */


    if (!X509_REQ_set_version(req_p, 0L)        /* Version 1 */
     || !X509_REQ_set_pubkey(req_p, key_p)) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "Failed to set stuff on X509_REQ\n");
        return -1;
    }

    if (!(name_p  = X509_REQ_get_subject_name(req_p))) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "Failed to make get X509_REQ_get_subject_name\n");
        return -1;
    }

    /* Build the DN */
    for (i = 0; i < dn_entries; i++) {
        if (!X509_NAME_add_entry_by_txt(name_p, dn_fields[i], MBSTRING_ASC,
                dn_values[i], -1, -1, 0)) {
            X509_REQ_free(req_p);
            EVP_PKEY_free(key_p);
            fprintf(stderr, "Failed to make the X509_NAME\n");
            return -1;
        }
    }

    if (!X509_REQ_sign(req_p, key_p, EVP_sha1())) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "X509_REQ_sign() failed\n");
        return -1;
    }

    /* save the private key to file (PKCS#1) */
    priv_p = NULL;
    priv_len = i2d_RSAPrivateKey(rsa_p, &priv_p);
    fwrite(priv_p, priv_len, 1, priv_f);
    OPENSSL_free(priv_p);

    EVP_PKEY_free(key_p);   /* nolonger need the EVP structure */

    /* save the CSR to file (PKCS#10) */
    i2d_X509_REQ_fp(req_f, req_p);
    X509_REQ_free(req_p);

    return 0;
}

int main(int argc, char *argv[])
{
    char    *dn_fields[] = { "O", "CN" };
    char    *dn_values[] = { "My Application", "tomcelic@selleck.com" };
    FILE    *req_f, *priv_f;

    req_f = fopen("selleck.csr", "w");
    priv_f = fopen("selleck.key", "w");

    if (build_and_save_csr(2, dn_fields, dn_values, req_f, priv_f) != 0) {
        fprintf(stderr, "Oh bother...\n");
        fclose(req_f);
        fclose(priv_f);
        exit(1);
    }

    fclose(req_f);
    fclose(priv_f);
    return 0;
}

我认为这一行可以换成创建自签名证书而不是签名请求的行?

/* save the CSR to file (PKCS#10) */
i2d_X509_REQ_fp(req_f, req_p);

这对我来说是全新的,所以我将不胜感激任何建议!

最佳答案

I presume this line could be swapped for one which creates a self signed cert instead of a sign request??

不,很抱歉这没那么容易。

X509_REQ 不是创建自签名证书的正确结构。仅用于CSR(Certificate Sign Request)管理,因此主要结构和函数(带有_REQ后缀)对您的用途无效。

但是,自签名证书的创建过程非常接近这个(CSR 是自签名的,您可以在 X509_REQ_sign 调用中注意到。)。

Here您可以找到整个过程的非常完整和详尽的答案,并且here自签名创建的示例。

作为解释 i2d_X509_REQ_fp 它用于将 X509 CSR 保存为 PKCS#10 格式,Info .

关于创建具有专有名称字段的自签名证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18912128/

相关文章:

python - 如何检查网站的 SSLv2 或 SSLv3?

security - HTTPS 下载/上传

c++ - 在 SHA256 哈希函数中使用的 Setw 和 setfill

ssl - 为域和子域创建自签名证书 - NET::ERR_CERT_COMMON_NAME_INVALID

https - Openssl TLS 扩展支持配置(服务器名称指示)

c - 如何将字符附加到字符串上?

c - C程序中未初始化内存位置的物理内存位置?

c - 如何排除pclint中的一些 "unable to open include file *.h"错误

调用在当前函数下声明的函数

vb.net - "The underlying connection was closed: An unexpected error occurred on a send."(Java/Apache SSL 加密 Web 服务的 VB .NET 客户端)