mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-29 17:23:38 +08:00
Update Tools
This commit is contained in:
20
src/asn1.c
20
src/asn1.c
@@ -738,6 +738,7 @@ const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 如果一个正确解析的OID并不在infos列表中,那么仍然返回1,但是调用方必须检查返回的info是否为空
|
||||
int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_t *nodes_cnt,
|
||||
const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
@@ -753,27 +754,30 @@ int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_
|
||||
if (*nodes_cnt == infos[i].nodes_cnt
|
||||
&& memcmp(nodes, infos[i].nodes, (*nodes_cnt) * sizeof(int)) == 0) {
|
||||
*info = &infos[i];
|
||||
return 1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
// 注意,此时虽然返回1,但是*info == NULL,因此调用方应该显式的判断info
|
||||
end:
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 和ex版本不同的是,如果在infos列表中未找到OID,返回错误
|
||||
int asn1_oid_info_from_der(const ASN1_OID_INFO **info, const ASN1_OID_INFO *infos, size_t count, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
uint32_t nodes[32];
|
||||
size_t nodes_cnt;
|
||||
|
||||
if ((ret = asn1_oid_info_from_der_ex(info, nodes, &nodes_cnt, infos, count, in, inlen)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
} else if (ret > 1) {
|
||||
if ((ret = asn1_oid_info_from_der_ex(info, nodes, &nodes_cnt, infos, count, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (*info == NULL) {
|
||||
asn1_object_identifier_print(stderr, 0, 0, "Unknown OID", NULL, nodes, nodes_cnt);
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1355,7 +1359,7 @@ int asn1_object_identifier_print(FILE *fp, int format, int indent, const char *l
|
||||
const uint32_t *nodes, size_t nodes_cnt)
|
||||
{
|
||||
size_t i;
|
||||
format_print(fp, format, indent, "%s: %s", label, name);
|
||||
format_print(fp, format, indent, "%s: %s", label, name ? name : "(unknown)");
|
||||
if (nodes) {
|
||||
fprintf(fp, " (");
|
||||
for (i = 0; i < nodes_cnt - 1; i++) {
|
||||
|
||||
259
src/cms.c
259
src/cms.c
@@ -63,6 +63,7 @@
|
||||
#include <gmssl/x509_ext.h>
|
||||
#include <gmssl/x509_crl.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/cms.h>
|
||||
|
||||
|
||||
@@ -110,14 +111,15 @@ int cms_content_type_from_name(const char *name)
|
||||
int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
size_t len = 0;
|
||||
|
||||
if (oid == -1) {
|
||||
return 0;
|
||||
}
|
||||
if (!(info = asn1_oid_info_from_oid(cms_content_types, cms_content_types_count, oid))) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) {
|
||||
if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -127,18 +129,11 @@ int cms_content_type_to_der(int oid, uint8_t **out, size_t *outlen)
|
||||
int cms_content_type_from_der(int *oid, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
const ASN1_OID_INFO *info;
|
||||
|
||||
*oid = 0;
|
||||
if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
|
||||
if ((ret = asn1_oid_info_from_der(&info, cms_content_types, cms_content_types_count, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if ((ret = asn1_oid_info_from_der(&info, cms_content_types, cms_content_types_count, &p, &len)) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
else *oid = -1;
|
||||
return ret;
|
||||
}
|
||||
*oid = info->oid;
|
||||
@@ -164,12 +159,13 @@ static int cms_content_info_data_header_to_der(size_t dlen, uint8_t **out, size_
|
||||
|
||||
int cms_content_info_header_to_der(int content_type, size_t content_len, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
size_t len = content_len; // 注意:由于header_to_der没有输出数据,因此需要加上数据的长度,header length 才是正确的值
|
||||
/*
|
||||
if (content_type == OID_cms_data) {
|
||||
return cms_content_info_data_header_to_der(content_len, out, outlen);
|
||||
}
|
||||
*/
|
||||
|
||||
if (cms_content_type_to_der(content_type, NULL, &len) != 1
|
||||
|| asn1_explicit_header_to_der(0, content_len, NULL, &len) < 0
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
@@ -254,23 +250,43 @@ int cms_content_info_print(FILE *fp, int fmt, int ind, const char *label, const
|
||||
if (cms_content_type_from_der(&content_type, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "contentType: %s\n", cms_content_type_name(content_type));
|
||||
|
||||
if ((ret = asn1_explicit_from_der(0, &content, &content_len, &d, &dlen)) < 0) goto err;
|
||||
if (ret) {
|
||||
/*
|
||||
if (content_type == OID_cms_data) {
|
||||
if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1) goto err;
|
||||
} else {
|
||||
if (asn1_sequence_from_der(&p, &len, &content, &content_len) != 1) goto err;
|
||||
}
|
||||
switch (content_type) {
|
||||
case OID_cms_data: format_bytes(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_signed_data: cms_signed_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_enveloped_data: cms_enveloped_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_signed_and_enveloped_data: cms_signed_and_enveloped_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_encrypted_data: cms_encrypted_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_key_agreement_info: cms_key_agreement_info_print(fp, fmt, ind, "content", p, len); break;
|
||||
*/
|
||||
|
||||
//format_bytes(stderr, 0, 0, "content", d, dlen);
|
||||
|
||||
if ((ret = asn1_explicit_from_der(0, &content, &content_len, &d, &dlen)) < 0) { error_print(); goto err; }
|
||||
if (ret == 0) { error_print(); goto err; }
|
||||
|
||||
if (content_type == OID_cms_data) {
|
||||
if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1
|
||||
|| asn1_length_is_zero(content_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_length_is_zero(content_len) != 1) goto err;
|
||||
format_bytes(fp, fmt, ind, "content", p, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (asn1_sequence_from_der(&p, &len, &content, &content_len) != 1) { error_print(); goto err; }
|
||||
|
||||
switch (content_type) {
|
||||
//case OID_cms_data: format_bytes(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_signed_data: cms_signed_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_enveloped_data: cms_enveloped_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_signed_and_enveloped_data: cms_signed_and_enveloped_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_encrypted_data: cms_encrypted_data_print(fp, fmt, ind, "content", p, len); break;
|
||||
case OID_cms_key_agreement_info: cms_key_agreement_info_print(fp, fmt, ind, "content", p, len); break;
|
||||
}
|
||||
if (asn1_length_is_zero(content_len) != 1) goto err;
|
||||
|
||||
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
@@ -367,8 +383,8 @@ int cms_enced_content_info_encrypt_to_der(
|
||||
{
|
||||
int ret;
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t enced_content[32 + content_len];
|
||||
size_t enced_content_len;
|
||||
uint8_t enced_content[32 + content_len]; // FIXME: 如果content_len 过长,会直接导致segment fault
|
||||
size_t enced_content_len = 100;
|
||||
|
||||
if (enc_algor != OID_sm4_cbc || keylen != 16 || ivlen != 16) {
|
||||
error_print();
|
||||
@@ -759,6 +775,7 @@ int cms_signer_info_sign_to_der(
|
||||
uint8_t **out, size_t *outlen)
|
||||
{
|
||||
SM3_CTX ctx = *sm3_ctx;
|
||||
int fixed_outlen = 1;
|
||||
uint8_t dgst[SM3_DIGEST_SIZE];
|
||||
uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
|
||||
size_t siglen;
|
||||
@@ -766,11 +783,12 @@ int cms_signer_info_sign_to_der(
|
||||
sm3_update(&ctx, authed_attrs, authed_attrs_len);
|
||||
sm3_finish(&ctx, dgst);
|
||||
|
||||
if (sm2_sign(sign_key, dgst, sig, &siglen) != 1) {
|
||||
|
||||
|
||||
if (sm2_sign_ex(sign_key, fixed_outlen, dgst, sig, &siglen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cms_signer_info_to_der(CMS_version_v1,
|
||||
issuer, issuer_len, serial_number, serial_number_len,
|
||||
OID_sm3, authed_attrs, authed_attrs_len,
|
||||
@@ -1206,6 +1224,7 @@ int cms_signed_data_verify_from_der(
|
||||
&authed_attrs, &authed_attrs_len,
|
||||
&unauthed_attrs, &unauthed_attrs_len,
|
||||
&signer_infos, &signer_infos_len) != 1) {
|
||||
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1264,7 +1283,8 @@ int cms_recipient_info_from_der(
|
||||
serial_number, serial_number_len, &d, &dlen) != 1
|
||||
|| x509_public_key_encryption_algor_from_der(pke_algor, params, params_len, &d, &dlen) != 1
|
||||
|| asn1_octet_string_from_der(enced_key, enced_key_len, &d, &dlen) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
// || asn1_length_is_zero(dlen) != 1
|
||||
) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1317,12 +1337,14 @@ int cms_recipient_info_encrypt_to_der(
|
||||
int pke_algor = OID_sm2encrypt;
|
||||
uint8_t enced_key[SM2_MAX_CIPHERTEXT_SIZE];
|
||||
size_t enced_key_len;
|
||||
int fixed_outlen = 1;
|
||||
|
||||
if (pke_algor != OID_sm2encrypt) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_encrypt(public_key, in, inlen, enced_key, &enced_key_len) != 1) {
|
||||
|
||||
if (sm2_encrypt_ex(public_key, fixed_outlen, in, inlen, enced_key, &enced_key_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1554,7 +1576,6 @@ int cms_enveloped_data_encrypt_to_der(
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
len = 0;
|
||||
if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1
|
||||
|| asn1_set_to_der(rcpt_infos, rcpt_infos_len, NULL, &len) != 1
|
||||
@@ -2048,9 +2069,20 @@ int cms_set_data(uint8_t *cms, size_t *cmslen, const uint8_t *d, size_t dlen)
|
||||
int oid = OID_cms_data;
|
||||
size_t len = 0;
|
||||
|
||||
if (asn1_octet_string_to_der(d, dlen, NULL, &len) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cmslen = 0;
|
||||
if (asn1_octet_string_to_der(d, dlen, NULL, &len) < 0
|
||||
|| cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
if (!cms) {
|
||||
uint8_t data[1];
|
||||
if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
|| asn1_octet_string_to_der(d, dlen, &cms, cmslen) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -2067,14 +2099,25 @@ int cms_encrypt(uint8_t *cms, size_t *cmslen,
|
||||
int oid = OID_cms_encrypted_data;
|
||||
size_t len = 0;
|
||||
|
||||
*cmslen = 0;
|
||||
if (cms_encrypted_data_encrypt_to_der(
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
content_type, content, content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
NULL, &len) != 1
|
||||
|| cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
content_type, content, content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cmslen = 0;
|
||||
if (!cms) {
|
||||
uint8_t data[1];
|
||||
if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
|| cms_encrypted_data_encrypt_to_der(
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
content_type, content, content_len,
|
||||
@@ -2125,13 +2168,24 @@ int cms_sign(uint8_t *cms, size_t *cmslen,
|
||||
int oid = OID_cms_signed_data;
|
||||
size_t len = 0;
|
||||
|
||||
*cmslen = 0;
|
||||
if (cms_signed_data_sign_to_der(
|
||||
signers, signers_cnt,
|
||||
content_type, content, content_len,
|
||||
crls, crls_len,
|
||||
NULL, &len) != 1
|
||||
|| cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
signers, signers_cnt,
|
||||
content_type, content, content_len,
|
||||
crls, crls_len,
|
||||
NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cmslen = 0;
|
||||
if (!cms) {
|
||||
uint8_t data[1];
|
||||
if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
|| cms_signed_data_sign_to_der(
|
||||
signers, signers_cnt,
|
||||
content_type, content, content_len,
|
||||
@@ -2156,12 +2210,19 @@ int cms_verify(const uint8_t *cms, size_t cmslen,
|
||||
size_t cms_content_len;
|
||||
|
||||
if (cms_content_info_from_der(&cms_type, &cms_content, &cms_content_len, &cms, &cmslen) != 1
|
||||
|| asn1_check(cms_type != OID_cms_signed_data) != 1
|
||||
|| asn1_check(cms_content && cms_content_len) != 1
|
||||
|| asn1_length_is_zero(cmslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (cms_type != OID_cms_signed_data) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (cms_content_len <= 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cms_signed_data_verify_from_der(
|
||||
extra_certs, extra_certs_len,
|
||||
extra_crls, extra_crls_len,
|
||||
@@ -2188,15 +2249,26 @@ int cms_envelop(
|
||||
int oid = OID_cms_enveloped_data;
|
||||
size_t len = 0;
|
||||
|
||||
*cmslen = 0;
|
||||
if (cms_enveloped_data_encrypt_to_der(
|
||||
rcpt_certs, rcpt_certs_len,
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
content_type, content, content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
NULL, &len) != 1
|
||||
|| cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
rcpt_certs, rcpt_certs_len,
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
content_type, content, content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cmslen = 0;
|
||||
if (!cms) {
|
||||
uint8_t data[1];
|
||||
if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
|| cms_enveloped_data_encrypt_to_der(
|
||||
rcpt_certs, rcpt_certs_len,
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
@@ -2272,17 +2344,28 @@ int cms_sign_and_envelop(uint8_t *cms, size_t *cmslen,
|
||||
int oid = OID_cms_signed_and_enveloped_data;
|
||||
size_t len = 0;
|
||||
|
||||
*cmslen = 0;
|
||||
if (cms_signed_and_enveloped_data_encipher_to_der(
|
||||
signers, signers_cnt,
|
||||
rcpt_certs, rcpt_certs_len,
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
content_type, content, content_len,
|
||||
crls, crls_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
NULL, &len) != 1
|
||||
|| cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
signers, signers_cnt,
|
||||
rcpt_certs, rcpt_certs_len,
|
||||
enc_algor, key, keylen, iv, ivlen,
|
||||
content_type, content, content_len,
|
||||
crls, crls_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cmslen = 0;
|
||||
if (!cms) {
|
||||
uint8_t data[1];
|
||||
if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
|| cms_signed_and_enveloped_data_encipher_to_der(
|
||||
signers, signers_cnt,
|
||||
rcpt_certs, rcpt_certs_len,
|
||||
@@ -2372,10 +2455,21 @@ int cms_set_key_agreement_info(
|
||||
int oid = OID_cms_key_agreement_info;
|
||||
size_t len = 0;
|
||||
|
||||
*cmslen = 0;
|
||||
if (cms_key_agreement_info_to_der(CMS_version_v1, temp_public_key_r,
|
||||
user_cert, user_cert_len, user_id, user_id_len, NULL, &len) != 1
|
||||
|| cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
user_cert, user_cert_len, user_id, user_id_len, NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cmslen = 0;
|
||||
if (!cms) {
|
||||
uint8_t data[1];
|
||||
if (cms_content_info_to_der(oid, data, len, NULL, cmslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (cms_content_info_header_to_der(oid, len, &cms, cmslen) != 1
|
||||
|| cms_key_agreement_info_to_der(CMS_version_v1, temp_public_key_r,
|
||||
user_cert, user_cert_len, user_id, user_id_len, &cms, cmslen) != 1) {
|
||||
error_print();
|
||||
@@ -2384,16 +2478,41 @@ int cms_set_key_agreement_info(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cms_to_pem(const uint8_t *cms, size_t cms_len, FILE *fp)
|
||||
{
|
||||
if (pem_write(fp, PEM_CMS, cms, cms_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cms_from_pem(uint8_t *cms, size_t *cms_len, size_t maxlen, FILE *fp)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = pem_read(fp, PEM_CMS, cms, cms_len, maxlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cms_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
|
||||
{
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
|
||||
|
||||
if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) goto err;
|
||||
|
||||
|
||||
cms_content_info_print(fp, fmt, ind, label, d, dlen);
|
||||
if (asn1_length_is_zero(alen) != 1) goto err;
|
||||
//if (asn1_length_is_zero(alen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ typedef struct {
|
||||
|
||||
DIGEST_TABLE digest_table[] = {
|
||||
{ OID_sm3, "sm3", "SM3" },
|
||||
{ OID_md5, "md5", "MD5" },
|
||||
// { OID_md5, "md5", "MD5" },
|
||||
{ OID_sha1, "sha1", "SHA-1" },
|
||||
{ OID_sha224, "sha224", "SHA-224" },
|
||||
{ OID_sha256, "sha256", "SHA-256" },
|
||||
@@ -131,8 +131,10 @@ const DIGEST *digest_from_name(const char *name)
|
||||
{
|
||||
if (!strcmp(name, "sm3") || !strcmp(name, "SM3")) {
|
||||
return DIGEST_sm3();
|
||||
/*
|
||||
} else if (!strcmp(name, "md5") || !strcmp(name, "MD5")) {
|
||||
return DIGEST_md5();
|
||||
*/
|
||||
} else if (!strcmp(name, "sha1") || !strcmp(name, "SHA1")) {
|
||||
return DIGEST_sha1();
|
||||
} else if (!strcmp(name, "sha224") || !strcmp(name, "SHA224")) {
|
||||
@@ -196,7 +198,7 @@ const DIGEST *DIGEST_sm3(void)
|
||||
return &sm3_digest_object;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#include <gmssl/md5.h>
|
||||
|
||||
static int md5_digest_init(DIGEST_CTX *ctx)
|
||||
@@ -243,6 +245,7 @@ const DIGEST *DIGEST_md5(void)
|
||||
{
|
||||
return &md5_digest_object;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#include <gmssl/sha1.h>
|
||||
@@ -292,7 +295,6 @@ const DIGEST *DIGEST_sha1(void)
|
||||
return &sha1_digest_object;
|
||||
}
|
||||
|
||||
|
||||
#include <gmssl/sha2.h>
|
||||
|
||||
static int sha224_digest_init(DIGEST_CTX *ctx)
|
||||
|
||||
@@ -97,6 +97,10 @@ int pem_read(FILE *fp, const char *name, uint8_t *data, size_t *datalen, size_t
|
||||
|
||||
if (strcmp(line, begin_line) != 0) {
|
||||
// FIXME: 这里是不是应该容忍一些错误呢?
|
||||
|
||||
fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, line);
|
||||
fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, begin_line);
|
||||
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -697,12 +697,6 @@ void sm2_fn_mul(SM2_BN r, const SM2_BN a, const SM2_BN b)
|
||||
uint64_t c[9] = {0,0,0,0,0,0,0,0,0x100000000};
|
||||
sm2_bn288_sub(q, c, q);
|
||||
sm2_bn288_add(zl, q, zl);
|
||||
printf("******\n");
|
||||
printf("******\n");
|
||||
printf("******\n");
|
||||
printf("******\n");
|
||||
printf("******\n");
|
||||
|
||||
}
|
||||
|
||||
//printf("r = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n");
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/mem.h>
|
||||
#include <gmssl/sm2.h>
|
||||
#include <gmssl/sm3.h>
|
||||
#include <gmssl/asn1.h>
|
||||
@@ -58,7 +59,7 @@
|
||||
|
||||
#define print_bn(str,a) sm2_bn_print(stderr,0,4,str,a)
|
||||
|
||||
int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig)
|
||||
int sm2_do_sign_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t dgst[32], SM2_SIGNATURE *sig)
|
||||
{
|
||||
SM2_JACOBIAN_POINT _P, *P = &_P;
|
||||
SM2_BN d;
|
||||
@@ -68,12 +69,12 @@ int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig)
|
||||
SM2_BN r;
|
||||
SM2_BN s;
|
||||
|
||||
retry:
|
||||
sm2_bn_from_bytes(d, key->private_key);
|
||||
|
||||
// e = H(M)
|
||||
sm2_bn_from_bytes(e, dgst); //print_bn("e", e);
|
||||
|
||||
retry:
|
||||
// e被重用了,注意retry的位置!
|
||||
|
||||
// rand k in [1, n - 1]
|
||||
do {
|
||||
@@ -107,17 +108,31 @@ retry:
|
||||
sm2_fn_inv(e, e); //print_bn("(1+d)^-1", e);
|
||||
sm2_fn_mul(s, e, k); //print_bn("s = ((1 + d)^-1 * (k - r * d)) mod n", s);
|
||||
|
||||
sm2_bn_clean(d);
|
||||
sm2_bn_clean(k);
|
||||
sm2_bn_to_bytes(r, sig->r); //print_bn("r", r);
|
||||
sm2_bn_to_bytes(s, sig->s); //print_bn("s", s);
|
||||
|
||||
if (fixed_outlen) {
|
||||
uint8_t buf[72];
|
||||
uint8_t *p = buf;
|
||||
size_t len = 0;
|
||||
sm2_signature_to_der(sig, &p, &len);
|
||||
if (len != 71) {
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
sm2_bn_clean(d);
|
||||
sm2_bn_clean(k);
|
||||
gmssl_secure_clear(d, sizeof(d));
|
||||
gmssl_secure_clear(e, sizeof(e));
|
||||
gmssl_secure_clear(k, sizeof(k));
|
||||
gmssl_secure_clear(x, sizeof(x));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig)
|
||||
{
|
||||
return sm2_do_sign_ex(key, 0, dgst, sig);
|
||||
}
|
||||
|
||||
int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig)
|
||||
{
|
||||
SM2_JACOBIAN_POINT _P, *P = &_P;
|
||||
@@ -161,12 +176,12 @@ int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATUR
|
||||
sm2_bn_from_bytes(e, dgst); //print_bn("e = H(M)", e);
|
||||
sm2_fn_add(e, e, x); //print_bn("e + x (mod n)", e);
|
||||
|
||||
|
||||
// check if r == r'
|
||||
if (sm2_bn_cmp(e, r) == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
if (sm2_bn_cmp(e, r) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen)
|
||||
@@ -231,7 +246,7 @@ int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uin
|
||||
|
||||
#define SM2_SIGNATURE_MAX_DER_SIZE 77
|
||||
|
||||
int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen)
|
||||
int sm2_sign_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t dgst[32], uint8_t *sig, size_t *siglen)
|
||||
{
|
||||
SM2_SIGNATURE signature;
|
||||
uint8_t *p;
|
||||
@@ -246,7 +261,7 @@ int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *s
|
||||
|
||||
p = sig;
|
||||
*siglen = 0;
|
||||
if (sm2_do_sign(key, dgst, &signature) != 1
|
||||
if (sm2_do_sign_ex(key, fixed_outlen, dgst, &signature) != 1
|
||||
|| sm2_signature_to_der(&signature, &p, siglen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -254,6 +269,11 @@ int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *s
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen)
|
||||
{
|
||||
return sm2_sign_ex(key, 0, dgst, sig, siglen);
|
||||
}
|
||||
|
||||
int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen)
|
||||
{
|
||||
int ret;
|
||||
@@ -497,7 +517,7 @@ int sm2_kdf(const uint8_t *in, size_t inlen, size_t outlen, uint8_t *out)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out)
|
||||
int sm2_do_encrypt_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out)
|
||||
{
|
||||
SM2_BN k;
|
||||
SM2_JACOBIAN_POINT _P, *P = &_P;
|
||||
@@ -505,15 +525,22 @@ int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPH
|
||||
uint8_t buf[64];
|
||||
int i;
|
||||
|
||||
retry:
|
||||
// rand k in [1, n - 1]
|
||||
do {
|
||||
sm2_bn_rand_range(k, SM2_N);
|
||||
} while (sm2_bn_is_zero(k));
|
||||
sm2_bn_rand_range(k, SM2_N);
|
||||
if (sm2_bn_is_zero(k)) goto retry;
|
||||
|
||||
// C1 = k * G = (x1, y1)
|
||||
sm2_jacobian_point_mul_generator(P, k);
|
||||
sm2_jacobian_point_to_bytes(P, (uint8_t *)&out->point);
|
||||
|
||||
if (fixed_outlen) {
|
||||
size_t xlen = 0, ylen = 0;
|
||||
asn1_integer_to_der(out->point.x, 32, NULL, &xlen);
|
||||
if (xlen != 34) goto retry;
|
||||
asn1_integer_to_der(out->point.y, 32, NULL, &ylen);
|
||||
if (ylen != 34) goto retry;
|
||||
}
|
||||
|
||||
// Q = k * P = (x2, y2)
|
||||
sm2_jacobian_point_from_bytes(P, (uint8_t *)&key->public_key);
|
||||
@@ -543,6 +570,11 @@ int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPH
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out)
|
||||
{
|
||||
return sm2_do_encrypt_ex(key, 0, in, inlen, out);
|
||||
}
|
||||
|
||||
int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen)
|
||||
{
|
||||
uint32_t inlen;
|
||||
@@ -683,7 +715,7 @@ int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const ui
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
|
||||
int sm2_encrypt_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
|
||||
{
|
||||
SM2_CIPHERTEXT C;
|
||||
|
||||
@@ -695,7 +727,7 @@ int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *ou
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_do_encrypt(key, in, inlen, &C) != 1) {
|
||||
if (sm2_do_encrypt_ex(key, fixed_outlen, in, inlen, &C) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -707,6 +739,11 @@ int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *ou
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
|
||||
{
|
||||
return sm2_encrypt_ex(key, 0, in, inlen, out, outlen);
|
||||
}
|
||||
|
||||
int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
|
||||
{
|
||||
SM2_CIPHERTEXT C;
|
||||
|
||||
@@ -53,8 +53,7 @@
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
#include <gmssl/x509_alg.h>
|
||||
|
||||
|
||||
static uint32_t oid_sm3[] = { 1,2,156,10197,1,401 };
|
||||
@@ -271,21 +270,20 @@ static uint32_t oid_rsasign_with_sha256[] = { 1,2,840,113549,1,1,11 };
|
||||
static uint32_t oid_rsasign_with_sha384[] = { 1,2,840,113549,1,1,12 };
|
||||
static uint32_t oid_rsasign_with_sha512[] = { 1,2,840,113549,1,1,13 };
|
||||
|
||||
#define X509_ALGOR_OPT_NULL_PARAM 1
|
||||
|
||||
static const ASN1_OID_INFO x509_sign_algors[] = {
|
||||
{ OID_sm2sign_with_sm3, "sm2sign-with-sm3", oid_sm2sign_with_sm3, sizeof(oid_sm2sign_with_sm3)/sizeof(int), 0 },
|
||||
{ OID_rsasign_with_sm3, "rsasign-with-sm3", oid_rsasign_with_sm3, sizeof(oid_rsasign_with_sm3)/sizeof(int), X509_ALGOR_OPT_NULL_PARAM },
|
||||
{ OID_ecdsa_with_sha1, "ecdsa-with-sha1", oid_ecdsa_with_sha1, sizeof(oid_ecdsa_with_sha1)/sizeof(int), 0 },
|
||||
{ OID_ecdsa_with_sha224, "ecdsa-with-sha224", oid_ecdsa_with_sha224, sizeof(oid_ecdsa_with_sha224)/sizeof(int), 0} ,
|
||||
{ OID_ecdsa_with_sha256, "ecdsa-with-sha256", oid_ecdsa_with_sha256, sizeof(oid_ecdsa_with_sha256)/sizeof(int), 0},
|
||||
{ OID_ecdsa_with_sha384, "ecdsa-with-sha384", oid_ecdsa_with_sha384, sizeof(oid_ecdsa_with_sha384)/sizeof(int), 0 },
|
||||
{ OID_ecdsa_with_sha512, "ecdsa-with-sha512", oid_ecdsa_with_sha512, sizeof(oid_ecdsa_with_sha512)/sizeof(int), 0 },
|
||||
{ OID_rsasign_with_sha1, "sha1WithRSAEncryption", oid_rsasign_with_sha1, sizeof(oid_rsasign_with_sha1)/sizeof(int), 0 },
|
||||
{ OID_rsasign_with_sha224, "sha224WithRSAEncryption", oid_rsasign_with_sha224, sizeof(oid_rsasign_with_sha224)/sizeof(int), X509_ALGOR_OPT_NULL_PARAM },
|
||||
{ OID_rsasign_with_sha256, "sha256WithRSAEncryption", oid_rsasign_with_sha256, sizeof(oid_rsasign_with_sha256)/sizeof(int), X509_ALGOR_OPT_NULL_PARAM },
|
||||
{ OID_rsasign_with_sha384, "sha384WithRSAEncryption", oid_rsasign_with_sha384, sizeof(oid_rsasign_with_sha384)/sizeof(int), X509_ALGOR_OPT_NULL_PARAM },
|
||||
{ OID_rsasign_with_sha512, "sha512WithRSAEncryption", oid_rsasign_with_sha512, sizeof(oid_rsasign_with_sha512)/sizeof(int), X509_ALGOR_OPT_NULL_PARAM },
|
||||
{ OID_sm2sign_with_sm3, "sm2sign-with-sm3", oid_sm2sign_with_sm3, sizeof(oid_sm2sign_with_sm3)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM },
|
||||
{ OID_rsasign_with_sm3, "rsasign-with-sm3", oid_rsasign_with_sm3, sizeof(oid_rsasign_with_sm3)/sizeof(int), 1 },
|
||||
{ OID_ecdsa_with_sha1, "ecdsa-with-sha1", oid_ecdsa_with_sha1, sizeof(oid_ecdsa_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM },
|
||||
{ OID_ecdsa_with_sha224, "ecdsa-with-sha224", oid_ecdsa_with_sha224, sizeof(oid_ecdsa_with_sha224)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM } ,
|
||||
{ OID_ecdsa_with_sha256, "ecdsa-with-sha256", oid_ecdsa_with_sha256, sizeof(oid_ecdsa_with_sha256)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM },
|
||||
{ OID_ecdsa_with_sha384, "ecdsa-with-sha384", oid_ecdsa_with_sha384, sizeof(oid_ecdsa_with_sha384)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM },
|
||||
{ OID_ecdsa_with_sha512, "ecdsa-with-sha512", oid_ecdsa_with_sha512, sizeof(oid_ecdsa_with_sha512)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM },
|
||||
{ OID_rsasign_with_sha1, "sha1WithRSAEncryption", oid_rsasign_with_sha1, sizeof(oid_rsasign_with_sha1)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM },
|
||||
{ OID_rsasign_with_sha224, "sha224WithRSAEncryption", oid_rsasign_with_sha224, sizeof(oid_rsasign_with_sha224)/sizeof(int), 1 },
|
||||
{ OID_rsasign_with_sha256, "sha256WithRSAEncryption", oid_rsasign_with_sha256, sizeof(oid_rsasign_with_sha256)/sizeof(int), 1 },
|
||||
{ OID_rsasign_with_sha384, "sha384WithRSAEncryption", oid_rsasign_with_sha384, sizeof(oid_rsasign_with_sha384)/sizeof(int), 1 },
|
||||
{ OID_rsasign_with_sha512, "sha512WithRSAEncryption", oid_rsasign_with_sha512, sizeof(oid_rsasign_with_sha512)/sizeof(int), 1 },
|
||||
};
|
||||
|
||||
static const int x509_sign_algors_count =
|
||||
|
||||
147
src/x509_cer.c
147
src/x509_cer.c
@@ -329,16 +329,26 @@ int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label
|
||||
if (fmt & ASN1_FMT_FULL) {
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
}
|
||||
if (x509_name_type_from_der(&oid, &d, &dlen) != 1) goto err;
|
||||
if (fmt & ASN1_FMT_FULL)
|
||||
|
||||
if (x509_name_type_from_der(&oid, &d, &dlen) != 1) goto err;
|
||||
asn1_object_identifier_print(fp, fmt, ind, "type", x509_name_type_name(oid), NULL, 0);
|
||||
|
||||
if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err;
|
||||
if (fmt & ASN1_FMT_FULL)
|
||||
x509_directory_name_print(fp, fmt, ind, "value", tag, val, vlen);
|
||||
else x509_directory_name_print(fp, fmt, ind, x509_name_type_name(oid), tag, val, vlen);
|
||||
|
||||
if (oid == OID_email_address) {
|
||||
if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err;
|
||||
format_string(fp, fmt, ind, "value", val, vlen);
|
||||
} else {
|
||||
if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err;
|
||||
x509_directory_name_print(fp, fmt, ind, "value", tag, val, vlen);
|
||||
}
|
||||
} else {
|
||||
if (x509_name_type_from_der(&oid, &d, &dlen) != 1) { error_print(); goto err; }
|
||||
if (oid == OID_email_address) {
|
||||
if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err;
|
||||
format_string(fp, fmt, ind, "emailAddress", val, vlen);
|
||||
} else {
|
||||
if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err;
|
||||
x509_directory_name_print(fp, fmt, ind, x509_name_type_name(oid), tag, val, vlen);
|
||||
}
|
||||
}
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
return 1;
|
||||
err:
|
||||
@@ -398,12 +408,17 @@ int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
}
|
||||
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
x509_attr_type_and_value_print(fp, fmt, ind, "AttributeTypeAndValue", p, len);
|
||||
while (dlen) {
|
||||
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
x509_attr_type_and_value_print(fp, fmt, ind, "AttributeTypeAndValue", p, len);
|
||||
x509_attr_type_and_value_print(fp, fmt, ind + 4, "AttributeTypeAndValue", p, len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -532,21 +547,43 @@ int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_name_get_printable(const uint8_t *d, size_t dlen, char *str, size_t maxlen)
|
||||
{
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen)
|
||||
{
|
||||
error_print();
|
||||
return -1;
|
||||
const uint8_t *rdn_d;
|
||||
size_t rdn_dlen;
|
||||
|
||||
while (dlen) {
|
||||
int attr_oid;
|
||||
int attr_tag;
|
||||
const uint8_t *attr_val;
|
||||
size_t attr_vlen;
|
||||
|
||||
if (asn1_set_from_der(&rdn_d, &rdn_dlen, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
while (rdn_dlen) {
|
||||
if (x509_attr_type_and_value_from_der(&attr_oid, &attr_tag, &attr_val, &attr_vlen,
|
||||
&rdn_d, &rdn_dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (attr_oid == oid) {
|
||||
*tag = attr_tag;
|
||||
*val = attr_val;
|
||||
*vlen = attr_vlen;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen)
|
||||
{
|
||||
error_print();
|
||||
int ret;
|
||||
ret = x509_name_get_value_by_type(d, dlen, OID_at_common_name, tag, val, vlen);
|
||||
if (ret < 0) error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -653,6 +690,7 @@ int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
}
|
||||
break;
|
||||
case OID_ce_key_usage:
|
||||
case OID_netscape_cert_type:
|
||||
if (asn1_bits_from_der(&ival, &val, &vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -665,6 +703,11 @@ int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
}
|
||||
break;
|
||||
case OID_netscape_cert_comment:
|
||||
if (asn1_ia5_string_from_der((const char **)&p, &len, &val, &vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_ct_precertificate_scts:
|
||||
case OID_undef:
|
||||
p = val;
|
||||
@@ -700,6 +743,7 @@ int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
case OID_ce_crl_distribution_points: return x509_crl_distribution_points_print(fp, fmt, ind, name, p, len);
|
||||
case OID_ce_inhibit_any_policy: format_print(fp, fmt, ind, "%s: %d\n", name, ival);
|
||||
case OID_ce_freshest_crl: return x509_freshest_crl_print(fp, fmt, ind, name, p, len);
|
||||
case OID_netscape_cert_type: return x509_netscape_cert_type_print(fp, fmt, ind, name, ival);
|
||||
case OID_netscape_cert_comment: return format_string(fp, fmt, ind, name, p, len);
|
||||
default: format_bytes(fp, fmt, ind, "extnValue", p, len);
|
||||
}
|
||||
@@ -1132,12 +1176,15 @@ int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1
|
||||
|| asn1_length_is_zero(alen) != 1) {
|
||||
if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
x509_certificate_print(fp, fmt, ind, label, d, dlen);
|
||||
if (asn1_length_is_zero(alen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1307,10 +1354,27 @@ int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_certs_from_pem(const uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp)
|
||||
int x509_certs_from_pem(uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp)
|
||||
{
|
||||
error_print();
|
||||
return -1;
|
||||
int ret;
|
||||
size_t len, total_len = 0;
|
||||
|
||||
for (;;) {
|
||||
if ((ret = x509_cert_from_pem(d, &len, maxlen, fp)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
} else if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
d += len;
|
||||
total_len += len;
|
||||
maxlen -= len;
|
||||
}
|
||||
*dlen = total_len;
|
||||
if (!total_len) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt)
|
||||
@@ -1324,15 +1388,42 @@ int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt)
|
||||
|
||||
int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen)
|
||||
{
|
||||
error_print();
|
||||
return -1;
|
||||
const uint8_t *a;
|
||||
size_t alen;
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i <= index; i++) {
|
||||
if ((ret = x509_cert_from_der(&a, &alen, &d, &dlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
else error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*cert = a;
|
||||
*certlen = alen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen,
|
||||
const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen)
|
||||
{
|
||||
error_print();
|
||||
return -1;
|
||||
const uint8_t *a;
|
||||
size_t alen;
|
||||
const uint8_t *subj;
|
||||
size_t subj_len;
|
||||
|
||||
while (dlen) {
|
||||
if (x509_cert_from_der(&a, &alen, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (subj_len == subject_len && memcmp(subj, subject, subj_len) == 0) {
|
||||
*cert = a;
|
||||
*certlen = alen;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x509_certs_get_cert_by_issuer_and_serial_number(
|
||||
|
||||
@@ -416,7 +416,6 @@ const char *x509_crl_ext_id_name(int oid)
|
||||
{
|
||||
const ASN1_OID_INFO *info;
|
||||
if (!(info = asn1_oid_info_from_oid(x509_crl_exts, x509_crl_exts_count, oid))) {
|
||||
error_print();
|
||||
return NULL;
|
||||
}
|
||||
return info->name;
|
||||
@@ -449,7 +448,7 @@ int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_crl_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen)
|
||||
int x509_crl_ext_id_from_der_ex(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *p;
|
||||
@@ -457,11 +456,13 @@ int x509_crl_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen)
|
||||
const ASN1_OID_INFO *info;
|
||||
|
||||
*oid = 0;
|
||||
if ((ret = asn1_oid_info_from_der(&info, x509_crl_exts, x509_crl_exts_count, in, inlen)) != 1) {
|
||||
if ((ret = asn1_oid_info_from_der_ex(&info, nodes, nodes_cnt, x509_crl_exts, x509_crl_exts_count, in, inlen)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*oid = info->oid;
|
||||
if (info) {
|
||||
*oid = info->oid;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -635,13 +636,15 @@ int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint
|
||||
size_t vlen;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
uint32_t nodes[32];
|
||||
size_t nodes_cnt;
|
||||
int num;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (x509_crl_ext_id_from_der(&oid, &d, &dlen) != 1) goto err;
|
||||
format_print(fp, fmt, ind, "extnID: %s\n", x509_crl_ext_id_name(oid));
|
||||
if (x509_crl_ext_id_from_der_ex(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
|
||||
asn1_object_identifier_print(fp, fmt, ind, "extnID", x509_crl_ext_id_name(oid), nodes, nodes_cnt);
|
||||
if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical));
|
||||
if (asn1_octet_string_from_der(&v, &vlen, &d, &dlen) != 1) goto err;
|
||||
@@ -664,6 +667,11 @@ int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (asn1_any_from_der(&p, &len, &v, &vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
name = x509_crl_ext_id_name(oid);
|
||||
@@ -676,6 +684,7 @@ int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint
|
||||
case OID_ce_issuing_distribution_point: x509_issuing_distribution_point_print(fp, fmt, ind, name, p, len); break;
|
||||
case OID_ce_freshest_crl: x509_crl_distribution_points_print(fp, fmt, ind, name, p, len); break;
|
||||
case OID_pe_authority_info_access: x509_access_descriptions_print(fp, fmt, ind, name, p, len); break;
|
||||
default: format_bytes(fp, fmt, ind, "value", p, len);
|
||||
}
|
||||
if (asn1_length_is_zero(vlen) != 1) goto err;
|
||||
return 1;
|
||||
@@ -873,12 +882,22 @@ err:
|
||||
// FIXME: 这两个函数应该检查CRL格式是否正确
|
||||
int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
return asn1_any_to_der(a, alen, out, outlen);
|
||||
int ret;
|
||||
if ((ret = asn1_any_to_der(a, alen, out, outlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
return asn1_any_from_der(a, alen, in, inlen);
|
||||
int ret;
|
||||
if ((ret = asn1_any_from_der(a, alen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp)
|
||||
@@ -900,6 +919,44 @@ int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_crl_to_fp(const uint8_t *a, size_t alen, FILE *fp)
|
||||
{
|
||||
if (fwrite(a, 1, alen, fp) != alen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_crl_from_fp(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp)
|
||||
{
|
||||
size_t len;
|
||||
const uint8_t *d = a;
|
||||
size_t dlen;
|
||||
const uint8_t *crl;
|
||||
size_t crl_len;
|
||||
|
||||
if (!(len = fread(a, 1, maxlen, fp))) {
|
||||
if (feof(fp)) {
|
||||
return 0;
|
||||
} else {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
dlen = len;
|
||||
if (x509_crl_from_der(&crl, &crl_len, &d, &dlen) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*alen = len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
|
||||
{
|
||||
const uint8_t *d;
|
||||
|
||||
@@ -463,16 +463,17 @@ int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, con
|
||||
return ret;
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_TAG_IMPLICIT(0): *choice = 0; break;
|
||||
case ASN1_TAG_EXPLICIT(0): *choice = 0; break;
|
||||
case ASN1_TAG_IMPLICIT(1): *choice = 1; break;
|
||||
case ASN1_TAG_IMPLICIT(2): *choice = 2; break;
|
||||
case ASN1_TAG_IMPLICIT(3): *choice = 3; break;
|
||||
case ASN1_TAG_IMPLICIT(4): *choice = 4; break;
|
||||
case ASN1_TAG_IMPLICIT(5): *choice = 5; break;
|
||||
case ASN1_TAG_EXPLICIT(3): *choice = 3; break;
|
||||
case ASN1_TAG_EXPLICIT(4): *choice = 4; break;
|
||||
case ASN1_TAG_EXPLICIT(5): *choice = 5; break;
|
||||
case ASN1_TAG_IMPLICIT(6): *choice = 6; break;
|
||||
case ASN1_TAG_IMPLICIT(7): *choice = 7; break;
|
||||
case ASN1_TAG_IMPLICIT(8): *choice = 8; break;
|
||||
default:
|
||||
fprintf(stderr, "%s %d: tag = %x\n", __FILE__, __LINE__, tag);
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -481,9 +482,24 @@ int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, con
|
||||
|
||||
int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
switch (choice) {
|
||||
case 0:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
d = p;
|
||||
dlen = len;
|
||||
}
|
||||
switch (choice) {
|
||||
case 0: return x509_other_name_print(fp, fmt, ind, "otherName", d, dlen);
|
||||
case 1: return asn1_string_print(fp, fmt, ind, "rfc822Name", ASN1_TAG_IA5String, d, dlen);
|
||||
@@ -1211,19 +1227,18 @@ int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t *
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
else {
|
||||
*ca = -1;
|
||||
*path_len_cons = -1;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
if (asn1_boolean_from_der(ca, &d, &dlen) < 0
|
||||
|| asn1_int_from_der(path_len_cons, &d, &dlen) < 0
|
||||
|| asn1_check(ca >= 0 || path_len_cons >= 0) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (*ca < 0 && *path_len_cons < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (*ca < 0) *ca = 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -1237,6 +1252,7 @@ int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
|
||||
if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(val));
|
||||
else format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(0)); // 特殊对待,无论cA值是否编码均输出结果
|
||||
if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err;
|
||||
if (ret) format_print(fp, fmt, ind, "pathLenConstraint: %d\n", val);
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
@@ -1748,3 +1764,21 @@ int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *netscape_cert_types[] = {
|
||||
"SSL Client certificate",
|
||||
"SSL Server certificate",
|
||||
"S/MIME certificate",
|
||||
"Object-signing certificate",
|
||||
"Reserved for future use",
|
||||
"SSL CA certificate",
|
||||
"S/MIME CA certificate",
|
||||
"Object-signing CA certificate",
|
||||
};
|
||||
|
||||
int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits)
|
||||
{
|
||||
return asn1_bits_print(fp, fmt, ind, label, netscape_cert_types,
|
||||
sizeof(netscape_cert_types)/sizeof(netscape_cert_types[0]), bits);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ static uint32_t oid_at_country_name[] = { oid_at,6 };
|
||||
static uint32_t oid_at_serial_number[] = { oid_at,5 };
|
||||
static uint32_t oid_at_pseudonym[] = { oid_at,65 };
|
||||
static uint32_t oid_domain_component[] = { 0,9,2342,19200300,100,1,25 };
|
||||
static uint32_t oid_email_address[] = { 1,2,840,113549,1,9,1 };
|
||||
|
||||
#define OID_AT_CNT (sizeof(oid_at_name)/sizeof(int))
|
||||
|
||||
@@ -95,6 +96,7 @@ static const ASN1_OID_INFO x509_name_types[] = {
|
||||
{ OID_at_serial_number, "serialNumber", oid_at_serial_number, OID_AT_CNT },
|
||||
{ OID_at_pseudonym, "pseudonym", oid_at_pseudonym, OID_AT_CNT },
|
||||
{ OID_domain_component, "domainComponent", oid_domain_component, sizeof(oid_domain_component)/sizeof(int) },
|
||||
{ OID_email_address, "emailAddress", oid_email_address, sizeof(oid_email_address)/sizeof(int) },
|
||||
};
|
||||
|
||||
static const int x509_name_types_count
|
||||
@@ -168,6 +170,7 @@ static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; // crl_entry_ext
|
||||
static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; // crl_entry_ext
|
||||
static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; // crl_entry_ext
|
||||
#define OID_CE_CNT sizeof(oid_ce_subject_directory_attributes)/sizeof(int)
|
||||
static uint32_t oid_netscape_cert_type[] = { 2,16,840,1,113730,1,1 };
|
||||
static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 };
|
||||
static uint32_t oid_cert_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 };
|
||||
static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 };
|
||||
@@ -191,6 +194,7 @@ static const ASN1_OID_INFO x509_ext_ids[] = {
|
||||
{ OID_ce_crl_reasons, "CRLReasons", oid_ce_crl_reasons, OID_CE_CNT },
|
||||
{ OID_ce_invalidity_date, "InvalidityDate", oid_ce_invalidity_date, OID_CE_CNT },
|
||||
{ OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, OID_CE_CNT },
|
||||
{ OID_netscape_cert_type, "NetscapeCertType", oid_netscape_cert_type, sizeof(oid_netscape_cert_type)/sizeof(int) },
|
||||
{ OID_netscape_cert_comment, "NetscapeCertComment", oid_netscape_cert_comment, sizeof(oid_netscape_cert_comment)/sizeof(int) },
|
||||
{ OID_cert_authority_info_access, "CertificateAuthorityInformationAccess", oid_cert_authority_info_access, sizeof(oid_cert_authority_info_access)/sizeof(int) },
|
||||
{ OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) },
|
||||
|
||||
Reference in New Issue
Block a user