使用 OpenSSL 和 TPM 引擎创建自签名 x509 证书的实际步骤是什么?X509_sign(cert, key, EVP_sha1()) 对我来说似乎每次都失败。
我从 X509_sign 得到的错误代码是:
Error code 2147913847
使用 ERR_print_errors_fp 我得到:
3064825040:error:0D0DC006:asn1 encoding routines:func(220):EVP lib:a_sign.c:314:
我所做的是:
1)使用 TPM 创建密钥
2)将密钥 blob 写入文件
if ((outb = BIO_new_file(KEY_FILENAME, "w")) == NULL) {
fprintf(stderr, "Error opening file for write: %s\n", KEY_FILENAME);
Tspi_Context_CloseObject(tpm.hContext, hKey);
Tspi_Context_Close(tpm.hContext);
exit(-1);
}
blob_str = ASN1_OCTET_STRING_new();
if (!blob_str) {
fprintf(stderr, "Error allocating ASN1_OCTET_STRING\n");
Tspi_Context_CloseObject(tpm.hContext, hKey);
Tspi_Context_Close(tpm.hContext);
exit(-1);
}
ASN1_STRING_set(blob_str, blob, blob_size);
asn1_len = i2d_ASN1_OCTET_STRING(blob_str, &blob_asn1);
PEM_write_bio(outb, "TSS KEY BLOB", "", blob_asn1, asn1_len);
BIO_free(outb);
3)使用TPM引擎读取(2)中创建的文件并将其更改为EVP_PKEY
const char *engineId = "tpm";
ENGINE *e;
EVP_PKEY *key;
ENGINE_load_builtin_engines();
e = ENGINE_by_id(engineId);
if (!e) { // Engine not available
ERR_print_errors_fp(stderr);
ERR("ENGINE_by_id failed.");
return NULL;
}
if (!ENGINE_init(e)) { // Engine couldn't initialise
ERR_print_errors_fp(stderr);
ERR("ENGINE_init failed.");
ENGINE_free(e);
ENGINE_finish(e);
return NULL;
}
if (!ENGINE_set_default_RSA(e) || !ENGINE_set_default_RAND(e)) {
/* This should only happen when 'e' can't initialise, but the previous
* statement suggests it did. */
ERR_print_errors_fp(stderr);
ERR("ENGINE_init failed.");
ENGINE_free(e);
ENGINE_finish(e);
return NULL;
}
ENGINE_ctrl_cmd(e, "PIN", 0, SRK_PASSWORD, NULL, 0);
ENGINE_free(e);
if ((key = ENGINE_load_private_key(e, fileName, NULL, NULL)) == NULL) {
ERR_print_errors_fp(stderr);
ERR("Couldn't load TPM key \"%s\" from file.", fileName);
return NULL;
}
ENGINE_finish(e);
e = NULL;
4) 使用 (3) 中创建的 EVP_PKEY 生成证书
X509 *cert;
X509_NAME *name = NULL;
FILE * fp = NULL;
// pk = key;
cert = X509_new();
X509_set_version(cert, 2);
// serial = M_ASN1_INTEGER_new();
ASN1_INTEGER_set(X509_get_serialNumber(cert), 0);
X509_gmtime_adj(X509_get_notBefore(cert), 0);
X509_gmtime_adj(X509_get_notAfter(cert), (long)60 * 60 * 24 * CERT_VALIDITY);
X509_set_pubkey(cert, key);
name = X509_get_subject_name(cert);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (const unsigned char *)"SG", -1, -1, 0); //country
X509_NAME_add_entry_by_txt(name, "ST", MBSTRING_ASC, (const unsigned char *)"SG", -1, -1, 0); //state
X509_NAME_add_entry_by_txt(name, "L", MBSTRING_ASC, (const unsigned char *)"Singapore", -1, -1, 0); //locality
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (const unsigned char *)"org", -1, -1, 0); //organisation
X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_ASC, (const unsigned char *)"unit", -1, -1, 0); //organisational unit
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const unsigned char *)"name", -1, -1, 0); //common name
X509_set_issuer_name(cert, name); // Its self signed so set the issuer name to be the same as the subject.
PEM_write_PrivateKey(stdout, key, NULL, NULL, 0, NULL, NULL);
PEM_write_PUBKEY(stdout, key);
if (!X509_sign(cert, key, EVP_sha1())) {
printf("Error signing certificate\n");
printf("Error code %lu\n", ERR_get_error());
ERR_print_errors_fp(stderr);
return;
} else {
PEM_write_X509(stdout, cert);
fp = fopen("x509.cert", "wb");
if (fp != NULL) {
i2d_X509_fp(fp, cert);
}
fclose(fp);
X509_free(cert);
}
我做错了什么吗?请帮忙,我似乎找不到太多关于在 TPM 引擎中使用 OpenSSL 的文档。谢谢。