This commit is contained in:
Zhi Guan
2022-04-11 17:56:25 +08:00
parent c21972168d
commit 7e4dd76839
45 changed files with 5221 additions and 2979 deletions

View File

@@ -746,7 +746,9 @@ int asn1_oid_info_from_der_ex(const ASN1_OID_INFO **info, uint32_t *nodes, size_
if ((ret = asn1_object_identifier_from_der(nodes, nodes_cnt, in, inlen)) != 1) {
if (ret < 0) error_print();
if (ret == 0) error_print();
if (ret == 0) {
error_print();
}
return ret;
}
*info = NULL;
@@ -1272,6 +1274,7 @@ int asn1_length_le(size_t len1, size_t len2)
{
if (len1 > len2) {
error_print();
format_print(stderr, 0, 0, "%s: %zu <= %zu failed\n", __FUNCTION__, len1, len2);
return -1;
}
return 1;

View File

@@ -395,11 +395,13 @@ int cms_enced_content_info_encrypt_to_der(
return 1;
}
// 这个函数显然是有问题的调用方根本不知道应该准备多大的buffer
// 应该为content_len 输出给一个maxlen 的最大buffer值
int cms_enced_content_info_decrypt_from_der(
int *enc_algor, const uint8_t *key, size_t keylen,
int *content_type, uint8_t *content, size_t *content_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
const uint8_t **shared_info1, size_t *shared_info1_len,// 支持可选null输出
const uint8_t **shared_info2, size_t *shared_info2_len,// 支持可选null输出
const uint8_t **in, size_t *inlen)
{
int ret;
@@ -763,6 +765,7 @@ 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) {
error_print();
return -1;
@@ -819,6 +822,7 @@ int cms_signer_info_verify_from_der(
sm3_update(&sm3_ctx, *authed_attrs, *authed_attrs_len);
sm3_finish(&sm3_ctx, dgst);
if (sm2_verify(&public_key, dgst, sig, siglen) != 1) {
error_print();
return -1;
@@ -1056,14 +1060,14 @@ static int cms_implicit_signers_certs_to_der(int index,
int cms_signed_data_sign_to_der(
const CMS_CERTS_AND_KEY *signers, size_t signers_cnt,
int content_type, const uint8_t *content, size_t content_len,
int content_type, const uint8_t *data, size_t datalen,
const uint8_t *crls, size_t crls_len,
uint8_t **out, size_t *outlen)
{
int digest_algors[] = { OID_sm3 };
size_t digest_algors_cnt = sizeof(digest_algors)/sizeof(int);
uint8_t content_header[256];
size_t content_header_len = 0;
size_t content_header_len;
const uint8_t *certs;
size_t certs_len = 0;
uint8_t signer_infos[512];
@@ -1077,14 +1081,30 @@ int cms_signed_data_sign_to_der(
size_t len = 0;
size_t i;
// 当content_type == OID_cms_data 时data是raw data被封装为OCTET STRING编码输出
// 而content_type为其他类型时data均为TLV的DER数据
// 在to_der/from_der 中已经处理,但是计算哈希值时也需要做处理
p = content_header;
if (cms_content_info_header_to_der(content_type, content_len, &p, &content_header_len) != 1) {
error_print();
return -1;
content_header_len = 0;
if (content_type == OID_cms_data) {
size_t content_len = 0;
if (asn1_octet_string_to_der(data, datalen, NULL, &content_len) != 1
|| cms_content_info_header_to_der(content_type, content_len, &p, &content_header_len) != 1
|| asn1_octet_string_header_to_der(datalen, &p, &content_header_len) != 1) {
error_print();
return -1;
}
} else {
if (cms_content_info_header_to_der(content_type, datalen, &p, &content_header_len) != 1) {
error_print();
return -1;
}
}
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, content_header, content_header_len);
sm3_update(&sm3_ctx, content, content_len);
sm3_update(&sm3_ctx, data, datalen);
for (i = 0; i < signers_cnt; i++) {
if (x509_cert_get_issuer_and_serial_number(
@@ -1102,15 +1122,16 @@ int cms_signed_data_sign_to_der(
if (asn1_int_to_der(CMS_version_v1, NULL, &len) != 1
|| cms_digest_algors_to_der(digest_algors, digest_algors_cnt, NULL, &len) != 1
|| cms_content_info_to_der(content_type, content, content_len, NULL, &len) != 1
|| cms_implicit_signers_certs_to_der(0, signers, signers_cnt, NULL, &len) != 1
|| cms_content_info_to_der(content_type, data, datalen, NULL, &len) != 1
|| cms_implicit_signers_certs_to_der(0, signers, signers_cnt, NULL, &len) < 0
|| asn1_implicit_set_to_der(1, crls, crls_len, NULL, &len) < 0
|| asn1_set_to_der(signer_infos, signer_infos_len, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(CMS_version_v1, out, outlen) != 1
|| cms_digest_algors_to_der(digest_algors, digest_algors_cnt, out, outlen) != 1
|| cms_content_info_to_der(content_type, content, content_len, out, outlen) != 1
|| cms_implicit_signers_certs_to_der(0, signers, signers_cnt, out, outlen) != 1
|| asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) != 1
|| cms_content_info_to_der(content_type, data, datalen, out, outlen) != 1
|| cms_implicit_signers_certs_to_der(0, signers, signers_cnt, out, outlen) < 0
|| asn1_implicit_set_to_der(1, crls, crls_len, out, outlen) < 0
|| asn1_set_to_der(signer_infos, signer_infos_len, out, outlen) != 1) {
error_print();
return -1;
@@ -1154,12 +1175,14 @@ int cms_signed_data_verify_from_der(
*psigner_infos = signer_infos;
*psigner_infos_len = signer_infos_len;
content_info_header_len = 0;
if (cms_content_info_header_to_der(*content_type, *content_len,
&p, &content_info_header_len) != 1) {
error_print();
return -1;
}
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, content_info_header, content_info_header_len);
sm3_update(&sm3_ctx, *content, *content_len);
@@ -1276,7 +1299,7 @@ int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, cons
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_public_key_encryption_algor_print(fp, fmt, ind, "keyEncryptionAlgorithm", p, len);
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
format_bytes(fp, fmt, ind, "encryptedKey", d, dlen);
format_bytes(fp, fmt, ind, "encryptedKey", p, len);
if (asn1_length_is_zero(dlen) != 1) goto err;
return 1;
err:
@@ -1331,6 +1354,7 @@ int cms_recipient_info_decrypt_from_der(
size_t issuer_len;
const uint8_t *serial;
size_t serial_len;
uint8_t outbuf[SM2_MAX_PLAINTEXT_SIZE];
if (cms_recipient_info_from_der(&version,
&issuer, &issuer_len, &serial, &serial_len,
@@ -1344,16 +1368,48 @@ int cms_recipient_info_decrypt_from_der(
|| memcmp(issuer, rcpt_issuer, rcpt_issuer_len) != 0
|| serial_len != rcpt_serial_len
|| memcmp(serial, rcpt_serial, serial_len) != 0) {
error_print();
return 0;
}
if (pke_algor != OID_sm2encrypt || params || params_len) {
error_print();
return -1;
}
if (sm2_decrypt(sm2_key, enced_key, enced_key_len, outbuf, outlen) != 1) {
error_print();
return -1;
}
if (maxlen < *outlen) {
error_print();
return -1;
}
memcpy(out, outbuf, *outlen);
return 1;
}
if (sm2_decrypt(sm2_key, enced_key, enced_key_len, NULL, outlen) != 1
|| asn1_length_le(*outlen, maxlen) != 1
|| sm2_decrypt(sm2_key, enced_key, enced_key_len, out, outlen) != 1) {
int cms_recipient_infos_add_recipient_info(
uint8_t *d, size_t *dlen, size_t maxlen,
const SM2_KEY *public_key,
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len,
const uint8_t *in, size_t inlen)
{
size_t len = *dlen;
d += *dlen;
if (cms_recipient_info_encrypt_to_der(
public_key,
issuer, issuer_len,
serial, serial_len,
in, inlen,
NULL, &len) != 1
|| asn1_length_le(len, maxlen) != 1
|| cms_recipient_info_encrypt_to_der(
public_key,
issuer, issuer_len,
serial, serial_len,
in, inlen,
&d, dlen) != 1) {
error_print();
return -1;
}
@@ -1466,7 +1522,7 @@ int cms_enveloped_data_encrypt_to_der(
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t **out, size_t *outlen)
{
uint8_t rcpt_infos[512];
uint8_t rcpt_infos[1024]; // 到底需要多大?
size_t rcpt_infos_len = 0;
uint8_t *p = rcpt_infos;
size_t len = 0;
@@ -1979,7 +2035,7 @@ int cms_key_agreement_info_print(FILE *fp, int fmt, int ind, const char *label,
if (x509_cert_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_cert_print(fp, fmt, ind, "certificate", p, len);
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
format_bytes(fp, fmt, ind, "userID", p, len);
format_string(fp, fmt, ind, "userID", p, len);
if (asn1_length_is_zero(dlen) != 1) goto err;
return 1;
err:

View File

@@ -160,3 +160,84 @@ int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen,
}
return 1;
}
/*
int sm3_hkdf_extract(const uint8_t *salt, size_t saltlen,
const uint8_t *ikm, size_t ikmlen,
uint8_t *prk, size_t *prklen)
{
SM3_HMAC_CTX hmac_ctx;
if (!salt || saltlen == 0) {
uint8_t zeros[SM3_HMAC_SIZE] = {0};
if (sm3_hmac_init(&hmac_ctx, zeros, SM3_HMAC_SIZE) != 1) {
error_print();
return -1;
}
} else {
if (sm3_hmac_init(&hmac_ctx, salt, saltlen) != 1) {
error_print();
return -1;
}
}
if (sm3_hmac_update(&hmac_ctx, ikm, ikmlen) != 1
|| sm3_hmac_finish(&hmac_ctx, prk) != 1) {
error_print();
return -1;
}
*prklen = SM3_HMAC_SIZE;
return 1;
}
int sm3_hkdf_expand(const uint8_t *prk, size_t prklen,
const uint8_t *opt_info, size_t opt_infolen,
size_t L, uint8_t *okm)
{
SM3_HMAC_CTX hmac_ctx;
uint8_t T[SM3_HMAC_SIZE];
uint8_t counter = 0x01;
size_t len;
if (L > 0) {
if (sm3_hmac_init(&hmac_ctx, prk, prklen) != 1
|| sm3_hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0
|| sm3_hmac_update(&hmac_ctx, &counter, 1) != 1
|| sm3_hmac_finish(&hmac_ctx, T) != 1) {
error_print();
return -1;
}
counter++;
len = SM3_HMAC_SIZE;
if (len > L) {
len = L;
}
memcpy(okm, T, len);
okm += len;
L -= len;
}
while (L > 0) {
if (counter == 0) {
error_print();
return -1;
}
if (sm3_hmac_init(&hmac_ctx, digest, prk, prklen) != 1
|| sm3_hmac_update(&hmac_ctx, T, len) != 1
|| sm3_hmac_update(&hmac_ctx, opt_info, opt_infolen) < 0
|| sm3_hmac_update(&hmac_ctx, &counter, 1) != 1
|| sm3_hmac_finish(&hmac_ctx, T) != 1) {
error_print();
return -1;
}
counter++;
len = SM3_HMAC_SIZE;
if (len > L) {
len = L;
}
memcpy(okm, T, len);
okm += len;
L -= len;
}
return 1;
}
*/

View File

@@ -179,6 +179,48 @@ int pbkdf2_hmac_sm3_genkey(
const uint8_t *salt, size_t saltlen, size_t count,
size_t outlen, uint8_t *out)
{
return pbkdf2_genkey(DIGEST_sm3(), pass, passlen, salt, saltlen, count, outlen, out);
}
SM3_HMAC_CTX ctx;
SM3_HMAC_CTX ctx_tmpl;
uint32_t iter = 1;
uint8_t iter_be[4];
uint8_t tmp_block[SM3_DIGEST_SIZE];
uint8_t key_block[SM3_DIGEST_SIZE];
size_t len;
sm3_hmac_init(&ctx_tmpl, (uint8_t *)pass, passlen);
while (outlen > 0) {
size_t i;
PUTU32(iter_be, iter);
iter++;
ctx = ctx_tmpl;
sm3_hmac_update(&ctx, salt, saltlen);
sm3_hmac_update(&ctx, iter_be, sizeof(iter_be));
sm3_hmac_finish(&ctx, tmp_block);
memcpy(key_block, tmp_block, SM3_DIGEST_SIZE);
for (i = 1; i < count; i++) {
ctx = ctx_tmpl;
sm3_hmac_update(&ctx, tmp_block, SM3_DIGEST_SIZE);
sm3_hmac_finish(&ctx, tmp_block);
memxor(key_block, tmp_block, SM3_DIGEST_SIZE);
}
if (outlen < SM3_DIGEST_SIZE) {
memcpy(out, key_block, outlen);
out += outlen;
outlen = 0;
} else {
memcpy(out, key_block, SM3_DIGEST_SIZE);
out += len;
outlen -= len;
}
}
memset(&ctx, 0, sizeof(ctx));
memset(key_block, 0, sizeof(key_block));
memset(tmp_block, 0, sizeof(key_block));
return 1;
}

View File

@@ -61,5 +61,6 @@ int rand_bytes(uint8_t *buf, size_t len)
return -1;
}
fread(buf, 1, len, fp);
fclose(fp);
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
/*
* Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,69 +46,44 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
#include <immintrin.h>
int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key)
int rdrand_bytes(uint8_t *buf, size_t buflen)
{
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
sm2_public_key_print(fp, fmt, ind, "publicKey", key);
format_bytes(fp, fmt, ind, "privateKey", key->private_key, 32);
return 1;
}
uint64_t val;
uint8_t *p = (uint8_t *)&val;
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key)
{
return sm2_point_print(fp, fmt, ind, label, &pub_key->public_key);
}
int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P)
{
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
format_bytes(fp, fmt, ind, "x", P->x, 32);
format_bytes(fp, fmt, ind, "y", P->y, 32);
return 1;
}
int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
{
SM2_SIGNATURE sig;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (sm2_signature_from_der(&sig, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
while (buflen) {
size_t len = buflen >= sizeof(val) ? sizeof(val) : buflen;
if (_rdrand64_step(&val) != 1) {
error_print();
return -1;
}
memcpy(buf, p, len);
buf += len;
buflen -= len;
}
format_bytes(fp, fmt, ind, "r", sig.r, 32);
format_bytes(fp, fmt, ind, "s", sig.s, 32);
return 1;
}
int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
int rdseed_bytes(uint8_t *buf, size_t buflen)
{
uint8_t buf[512] = {0};
SM2_CIPHERTEXT *c = (SM2_CIPHERTEXT *)buf;
int i;
uint64_t val;
uint8_t *p = (uint8_t *)&val;
if (sm2_ciphertext_from_der(c, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
while (buflen) {
size_t len = buflen >= sizeof(val) ? sizeof(val) : buflen;
if (_rdseed64_step(&val) != 1) {
error_print();
return -1;
}
memcpy(buf, p, len);
buf += len;
buflen -= len;
}
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
format_bytes(fp, fmt, ind, "XCoordinate", c->point.x, 32);
format_bytes(fp, fmt, ind, "YCoordinate", c->point.y, 32);
format_bytes(fp, fmt, ind, "HASH", c->hash, 32);
format_bytes(fp, fmt, ind, "CipherText", c->ciphertext, c->ciphertext_size);
return 1;
}

1241
src/sm2_alg.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -60,183 +60,64 @@
#include <gmssl/x509_alg.h>
void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33])
int sm2_key_generate(SM2_KEY *key)
{
*out++ = (P->y[31] & 0x01) ? 0x03 : 0x02;
memcpy(out, P->x, 32);
}
SM2_BN x;
SM2_BN y;
SM2_JACOBIAN_POINT _P, *P = &_P;
void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65])
{
*out++ = 0x04;
memcpy(out, P, 64);
}
int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen)
{
if ((*in == 0x02 || *in == 0x03) && inlen == 33) {
if (sm2_point_from_x(P, in + 1, *in) != 1) {
error_print();
return -1;
}
} else if (*in == 0x04 && inlen == 65) {
if (sm2_point_from_xy(P, in + 1, in + 33) != 1) {
error_print();
return -1;
}
} else {
if (!key) {
error_print();
return -1;
}
memset(key, 0, sizeof(SM2_KEY));
do {
sm2_bn_rand_range(x, SM2_N);
} while (sm2_bn_is_zero(x));
sm2_bn_to_bytes(x, key->private_key);
sm2_jacobian_point_mul_generator(P, x);
sm2_jacobian_point_get_xy(P, x, y);
sm2_bn_to_bytes(x, key->public_key.x);
sm2_bn_to_bytes(y, key->public_key.y);
return 1;
}
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen)
int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32])
{
uint8_t octets[65];
if (!P) {
return 0;
}
sm2_point_to_uncompressed_octets(P, octets);
if (asn1_octet_string_to_der(octets, sizeof(octets), out, outlen) != 1) {
memcpy(&key->private_key, private_key, 32);
// FIXEM检查私钥是否在有效的范围内
if (sm2_point_mul_generator(&key->public_key, private_key) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen)
int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key)
{
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_octet_string_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (dlen != 65) {
error_print();
return -1;
}
if (sm2_point_from_octets(P, d, dlen) != 1) {
if (!key || !public_key) {
error_print();
return -1;
}
memset(key, 0, sizeof(SM2_KEY));
key->public_key = *public_key;
return 1;
}
int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen)
int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key)
{
size_t len = 0;
if (!sig) {
return 0;
}
if (asn1_integer_to_der(sig->r, 32, NULL, &len) != 1
|| asn1_integer_to_der(sig->s, 32, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_integer_to_der(sig->r, 32, out, outlen) != 1
|| asn1_integer_to_der(sig->s, 32, out, outlen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
sm2_public_key_print(fp, fmt, ind, "publicKey", key);
format_bytes(fp, fmt, ind, "privateKey", key->private_key, 32);
return 1;
}
int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
const uint8_t *r;
size_t rlen;
const uint8_t *s;
size_t slen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_integer_from_der(&r, &rlen, &d, &dlen) != 1
|| asn1_integer_from_der(&s, &slen, &d, &dlen) != 1
|| asn1_length_le(rlen, 32) != 1
|| asn1_length_le(slen, 32) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
memset(sig, 0, sizeof(*sig));
memcpy(sig->r + 32 - rlen, r, rlen); // 需要测试当r, s是比较小的整数时
memcpy(sig->s + 32 - slen, s, slen);
return 1;
}
/*
int sm2_ciphertext_size(size_t inlen, size_t *outlen)
{
*outlen = sizeof(SM2_CIPHERTEXT)-1+inlen;
return 1;
}
*/
int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *C, uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (!C) {
return 0;
}
if (asn1_integer_to_der(C->point.x, 32, NULL, &len) != 1
|| asn1_integer_to_der(C->point.y, 32, NULL, &len) != 1
|| asn1_octet_string_to_der(C->hash, 32, NULL, &len) != 1
|| asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_integer_to_der(C->point.x, 32, out, outlen) != 1
|| asn1_integer_to_der(C->point.y, 32, out, outlen) != 1
|| asn1_octet_string_to_der(C->hash, 32, out, outlen) != 1
|| asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_ciphertext_from_der(SM2_CIPHERTEXT *C, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
const uint8_t *x;
const uint8_t *y;
const uint8_t *hash;
const uint8_t *c;
size_t xlen, ylen, hashlen, clen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_integer_from_der(&x, &xlen, &d, &dlen) != 1
|| asn1_integer_from_der(&y, &ylen, &d, &dlen) != 1
|| asn1_octet_string_from_der(&hash, &hashlen, &d, &dlen) != 1
|| asn1_octet_string_from_der(&c, &clen, &d, &dlen) != 1
|| asn1_length_le(xlen, 32) != 1
|| asn1_length_le(ylen, 32) != 1
|| asn1_check(hashlen == 32) != 1
|| asn1_length_le(clen, SM2_MAX_PLAINTEXT_SIZE) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
memset(C, 0, sizeof(SM2_CIPHERTEXT));
memcpy(C->point.x, x, xlen);
memcpy(C->point.y, y, ylen);
memcpy(C->hash, hash, hashlen);
memcpy(C->ciphertext, c, clen);
C->ciphertext_size = (uint8_t)clen;
return 1;
}
// BIT STRING wrapping of uncompressed point
int sm2_public_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen)
{
uint8_t buf[65];
@@ -276,22 +157,41 @@ int sm2_public_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen)
return 1;
}
/*
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key)
{
const uint8_t *d;
size_t dlen;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (asn1_bit_octets_from_der(&d, &dlen, &a, &alen) != 1) goto err;
format_bytes(fp, fmt, ind, "", d, dlen);
return sm2_point_print(fp, fmt, ind, label, &pub_key->public_key);
}
int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen)
{
if (x509_public_key_algor_to_der(OID_ec_public_key, OID_sm2, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen)
{
int ret;
int oid;
int curve;
if ((ret = x509_public_key_algor_from_der(&oid, &curve, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (oid != OID_ec_public_key) {
printf("%s %d: oid = %d\n", __FILE__, __LINE__, oid);
error_print();
return -1;
}
if (curve != OID_sm2) {
error_print();
return -1;
}
return 1;
}
*/
int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen)
{
@@ -361,12 +261,18 @@ int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen)
error_print();
return -1;
}
// 这里的逻辑上应该是用一个新的公钥来接收公钥,并且判断这个和私钥是否一致
if (pubkey) {
if (sm2_public_key_from_der(key, &pubkey, &pubkey_len) != 1
SM2_KEY tmp_key;
if (sm2_public_key_from_der(&tmp_key, &pubkey, &pubkey_len) != 1
|| asn1_length_is_zero(pubkey_len) != 1) {
error_print();
return -1;
}
if (sm2_public_key_equ(key, &tmp_key) != 1) {
error_print();
return -1;
}
}
return 1;
}
@@ -377,38 +283,6 @@ int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const u
}
int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen)
{
if (x509_public_key_algor_to_der(OID_ec_public_key, OID_sm2, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen)
{
int ret;
int oid;
int curve;
if ((ret = x509_public_key_algor_from_der(&oid, &curve, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (oid != OID_ec_public_key) {
printf("%s %d: oid = %d\n", __FILE__, __LINE__, oid);
error_print();
return -1;
}
if (curve != OID_sm2) {
error_print();
return -1;
}
return 1;
}
#define SM2_PRIVATE_KEY_MAX_SIZE 512 // 需要测试这个buffer的最大值
int sm2_private_key_info_to_der(const SM2_KEY *sm2_key, uint8_t **out, size_t *outlen)
@@ -497,7 +371,7 @@ err:
return -1;
}
/*
#define SM2_PRIVATE_KEY_INFO_MAX_SIZE 512 // 计算长度
int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp)
@@ -530,9 +404,7 @@ int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, const uint8_t **attrs, size_
}
return 1;
}
#define SM2_POINT_MAX_SIZE (2 + 65)
*/
int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen)
{
@@ -567,6 +439,7 @@ int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *i
return 1;
}
/*
int sm2_private_key_to_pem(const SM2_KEY *a, FILE *fp)
{
uint8_t buf[512];
@@ -601,6 +474,7 @@ int sm2_private_key_from_pem(SM2_KEY *a, FILE *fp)
}
return 1;
}
*/
int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp)
{

View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,76 +52,233 @@
#include <stdlib.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
#include "endian.h"
#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)
{
SM2_JACOBIAN_POINT _P, *P = &_P;
SM2_BN d;
SM2_BN e;
SM2_BN k;
SM2_BN x;
SM2_BN r;
SM2_BN s;
sm2_bn_from_bytes(d, key->private_key);
// e = H(M)
sm2_bn_from_bytes(e, dgst); //print_bn("e", e);
retry:
// rand k in [1, n - 1]
do {
sm2_fn_rand(k);
} while (sm2_bn_is_zero(k));
//print_bn("k", k);
// (x, y) = kG
sm2_jacobian_point_mul_generator(P, k);
sm2_jacobian_point_get_xy(P, x, NULL);
//print_bn("x", x);
// r = e + x (mod n)
sm2_fn_add(r, e, x); //print_bn("r = e + x (mod n)", r);
/* if r == 0 or r + k == n re-generate k */
if (sm2_bn_is_zero(r)) {
goto retry;
}
sm2_bn_add(x, r, k);
if (sm2_bn_cmp(x, SM2_N) == 0) {
goto retry;
}
/* s = ((1 + d)^-1 * (k - r * d)) mod n */
sm2_fn_mul(e, r, d); //print_bn("r*d", e);
sm2_fn_sub(k, k, e); //print_bn("k-r*d", k);
sm2_fn_add(e, SM2_ONE, d); //print_bn("1 +d", e);
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);
sm2_bn_clean(d);
sm2_bn_clean(k);
return 1;
}
int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig)
{
SM2_JACOBIAN_POINT _P, *P = &_P;
SM2_JACOBIAN_POINT _R, *R = &_R;
SM2_BN r;
SM2_BN s;
SM2_BN e;
SM2_BN x;
SM2_BN t;
// parse signature values
sm2_bn_from_bytes(r, sig->r); //print_bn("r", r);
sm2_bn_from_bytes(s, sig->s); //print_bn("s", s);
if (sm2_bn_is_zero(r) == 1
|| sm2_bn_cmp(r, SM2_N) >= 0
|| sm2_bn_is_zero(s) == 1
|| sm2_bn_cmp(s, SM2_N) >= 0) {
error_print();
return -1;
}
// parse public key
sm2_jacobian_point_from_bytes(P, (const uint8_t *)&key->public_key);
//print_point("P", P);
// t = r + s (mod n)
// check t != 0
sm2_fn_add(t, r, s); //print_bn("t = r + s (mod n)", t);
if (sm2_bn_is_zero(t)) {
error_print();
return -1;
}
// Q = s * G + t * P
sm2_jacobian_point_mul_sum(R, t, P, s);
sm2_jacobian_point_get_xy(R, x, NULL);
//print_bn("x", x);
// e = H(M)
// r' = e + x (mod n)
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 {
return 0;
}
}
int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (!sig) {
return 0;
}
if (asn1_integer_to_der(sig->r, 32, NULL, &len) != 1
|| asn1_integer_to_der(sig->s, 32, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_integer_to_der(sig->r, 32, out, outlen) != 1
|| asn1_integer_to_der(sig->s, 32, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
const uint8_t *r;
size_t rlen;
const uint8_t *s;
size_t slen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_integer_from_der(&r, &rlen, &d, &dlen) != 1
|| asn1_integer_from_der(&s, &slen, &d, &dlen) != 1
|| asn1_length_le(rlen, 32) != 1
|| asn1_length_le(slen, 32) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
memset(sig, 0, sizeof(*sig));
memcpy(sig->r + 32 - rlen, r, rlen); // 需要测试当r, s是比较小的整数时
memcpy(sig->s + 32 - slen, s, slen);
return 1;
}
int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
{
SM2_SIGNATURE sig;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (sm2_signature_from_der(&sig, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind, "r", sig.r, 32);
format_bytes(fp, fmt, ind, "s", sig.s, 32);
return 1;
}
#define SM2_SIGNATURE_MAX_DER_SIZE 77
int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *der, size_t *derlen)
int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen)
{
SM2_SIGNATURE sig;
uint8_t *p = der;
size_t len = 0;
SM2_SIGNATURE signature;
uint8_t *p;
if (!der && derlen) {
*derlen = SM2_SIGNATURE_MAX_DER_SIZE;
return 1;
}
if (!key || !der || !derlen) {
if (!key
|| !dgst
|| !sig
|| !siglen) {
error_print();
return -1;
}
sm2_do_sign(key, dgst, &sig);
sm2_signature_to_der(&sig, &p, &len);
*derlen = len;
p = sig;
*siglen = 0;
if (sm2_do_sign(key, dgst, &signature) != 1
|| sm2_signature_to_der(&signature, &p, siglen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *der, size_t derlen)
int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen)
{
int ret;
SM2_SIGNATURE sig;
const uint8_t *p = der;
size_t len = derlen;
SM2_SIGNATURE signature;
const uint8_t *p;
size_t len;
if (!key || !der || !derlen) {
if (!key
|| !dgst
|| !sig
|| !siglen) {
error_print();
return -1;
}
if (sm2_signature_from_der(&sig, &p, &len) < 0
|| len > 0) {
p = sig;
if (sm2_signature_from_der(&signature, &p, &siglen) != 1
|| asn1_length_is_zero(siglen) != 1) {
error_print();
return -2;
return -1;
}
if ((ret = sm2_do_verify(key, dgst, &sig)) != 1) {
error_print(); // 此处应该判断ret是否为0如果返回的是0那么不应该输出错误日志会产生不必要的终端输出
if ((ret = sm2_do_verify(key, dgst, &signature)) != 1) {
if (ret < 0) error_print();
return ret;
}
return ret;
}
//FIXME: 由于每次加密的时候密文编码长度不同因此这个函数应该避免在out == NULL时输出一个长度
int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
size_t clen = sizeof(SM2_CIPHERTEXT)-1+inlen; // FIXME: not supported in MS VS
size_t cbuf[clen];
SM2_CIPHERTEXT *c = (SM2_CIPHERTEXT *)cbuf;
sm2_do_encrypt(key, in, inlen, c);
*outlen = 0;
sm2_ciphertext_to_der(c, &out, outlen);
return 1;
}
int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
size_t cbuf[inlen];
SM2_CIPHERTEXT *c = (SM2_CIPHERTEXT *)cbuf;
sm2_ciphertext_from_der(c, &in, &inlen); // FIXME: 检查是否有剩余长度
sm2_do_decrypt(key, c, out, outlen);
return 1;
}
@@ -170,6 +327,7 @@ int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t id
return -1;
}
if (strcmp(id, "1234567812345678") == 0) {
uint32_t digest[8] = {
0xadadedb5U, 0x0446043fU, 0x08a87aceU, 0xe86d2243U,
@@ -208,73 +366,376 @@ int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t id
int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen)
{
uint8_t z[32];
if (!ctx || !key || !id || idlen > SM2_MAX_ID_LENGTH) {
if (!ctx || !key) {
error_print();
return -1;
}
sm2_compute_z(z, &key->public_key, id, idlen);
ctx->key = *key;
sm3_init(&ctx->sm3_ctx);
sm3_update(&ctx->sm3_ctx, z, 32);
memcpy(&ctx->key, key, sizeof(SM2_KEY));
if (id) {
uint8_t z[SM3_DIGEST_SIZE];
if (idlen <= 0 || idlen > SM2_MAX_ID_LENGTH) {
error_print();
return -1;
}
sm2_compute_z(z, &key->public_key, id, idlen);
sm3_update(&ctx->sm3_ctx, z, sizeof(z));
}
return 1;
}
int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
{
sm3_update(&ctx->sm3_ctx, data, datalen);
if (!ctx) {
error_print();
return -1;
}
if (data && datalen > 0) {
sm3_update(&ctx->sm3_ctx, data, datalen);
}
return 1;
}
int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen)
{
uint8_t dgst[32];
sm3_finish(&ctx->sm3_ctx, dgst);
sm2_sign(&ctx->key, dgst, sig, siglen);
return 1;
}
int ret;
uint8_t dgst[SM3_DIGEST_SIZE];
int sm2_sign_resume(SM2_SIGN_CTX *ctx)
{
return 0;
if (!ctx || !sig || !siglen) {
error_print();
return -1;
}
sm3_finish(&ctx->sm3_ctx, dgst);
if ((ret = sm2_sign(&ctx->key, dgst, sig, siglen)) != 1) {
if (ret < 0) error_print();
return ret;
}
return 1;
}
int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen)
{
uint8_t z[32];
if (!ctx || !key || !id || idlen > SM2_MAX_ID_LENGTH) {
if (!ctx || !key) {
error_print();
return -1;
}
sm2_compute_z(z, &key->public_key, id, idlen);
ctx->key = *key;
sm3_init(&ctx->sm3_ctx);
sm3_update(&ctx->sm3_ctx, z, 32);
memcpy(&ctx->key, key, sizeof(SM2_KEY));
if (id) {
uint8_t z[SM3_DIGEST_SIZE];
if (idlen <= 0 || idlen > SM2_MAX_ID_LENGTH) {
error_print();
return -1;
}
sm2_compute_z(z, &key->public_key, id, idlen);
sm3_update(&ctx->sm3_ctx, z, sizeof(z));
}
return 1;
}
int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
{
sm3_update(&ctx->sm3_ctx, data, datalen);
if (!ctx) {
error_print();
return -1;
}
if (data && datalen > 0) {
sm3_update(&ctx->sm3_ctx, data, datalen);
}
return 1;
}
int sm2_verify_finish(SM2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen)
{
int ret;
uint8_t dgst[32];
uint8_t dgst[SM3_DIGEST_SIZE];
if (!ctx || !sig) {
error_print();
return -1;
}
sm3_finish(&ctx->sm3_ctx, dgst);
ret = sm2_verify(&ctx->key, dgst, sig, siglen);
return ret;
}
int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32])
{
memcpy(&key->private_key, private_key, 32);
if ((ret = sm2_verify(&ctx->key, dgst, sig, siglen)) != 1) {
if (ret < 0) error_print();
return ret;
}
return 1;
}
int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key)
int sm2_kdf(const uint8_t *in, size_t inlen, size_t outlen, uint8_t *out)
{
key->public_key = *public_key;
SM3_CTX ctx;
uint8_t counter_be[4];
uint8_t dgst[SM3_DIGEST_SIZE];
uint32_t counter = 1;
size_t len;
/*
size_t i; fprintf(stderr, "kdf input : ");
for (i = 0; i < inlen; i++) fprintf(stderr, "%02x", in[i]); fprintf(stderr, "\n");
*/
while (outlen) {
PUTU32(counter_be, counter);
counter++;
sm3_init(&ctx);
sm3_update(&ctx, in, inlen);
sm3_update(&ctx, counter_be, sizeof(counter_be));
sm3_finish(&ctx, dgst);
len = outlen < SM3_DIGEST_SIZE ? outlen : SM3_DIGEST_SIZE;
memcpy(out, dgst, len);
out += len;
outlen -= len;
}
memset(&ctx, 0, sizeof(SM3_CTX));
memset(dgst, 0, sizeof(dgst));
return 1;
}
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out)
{
SM2_BN k;
SM2_JACOBIAN_POINT _P, *P = &_P;
SM3_CTX sm3_ctx;
uint8_t buf[64];
int i;
// rand k in [1, n - 1]
do {
sm2_bn_rand_range(k, SM2_N);
} while (sm2_bn_is_zero(k));
// C1 = k * G = (x1, y1)
sm2_jacobian_point_mul_generator(P, k);
sm2_jacobian_point_to_bytes(P, (uint8_t *)&out->point);
// Q = k * P = (x2, y2)
sm2_jacobian_point_from_bytes(P, (uint8_t *)&key->public_key);
sm2_jacobian_point_mul(P, k, P);
sm2_jacobian_point_to_bytes(P, buf);
// t = KDF(x2 || y2, klen)
sm2_kdf(buf, sizeof(buf), inlen, out->ciphertext);
// C2 = M xor t
for (i = 0; i < inlen; i++) {
out->ciphertext[i] ^= in[i];
}
out->ciphertext_size = (uint32_t)inlen;
// C3 = Hash(x2 || m || y2)
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, buf, 32);
sm3_update(&sm3_ctx, in, inlen);
sm3_update(&sm3_ctx, buf + 32, 32);
sm3_finish(&sm3_ctx, out->hash);
return 1;
}
int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen)
{
uint32_t inlen;
SM2_BN d;
SM2_JACOBIAN_POINT _P, *P = &_P;
SM3_CTX sm3_ctx;
uint8_t buf[64];
uint8_t hash[32];
int i;
// FIXME: check SM2_CIPHERTEXT format
// check C1
sm2_jacobian_point_from_bytes(P, (uint8_t *)&in->point);
//point_print(stdout, P, 0, 2);
/*
if (!sm2_jacobian_point_is_on_curve(P)) {
fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__);
return -1;
}
*/
// d * C1 = (x2, y2)
sm2_bn_from_bytes(d, key->private_key);
sm2_jacobian_point_mul(P, d, P);
sm2_bn_clean(d);
sm2_jacobian_point_to_bytes(P, buf);
// t = KDF(x2 || y2, klen)
if ((inlen = in->ciphertext_size) <= 0) {
fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__);
return -1;
}
sm2_kdf(buf, sizeof(buf), inlen, out);
// M = C2 xor t
for (i = 0; i < inlen; i++) {
out[i] ^= in->ciphertext[i];
}
*outlen = inlen;
// u = Hash(x2 || M || y2)
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, buf, 32);
sm3_update(&sm3_ctx, out, inlen);
sm3_update(&sm3_ctx, buf + 32, 32);
sm3_finish(&sm3_ctx, hash);
// check if u == C3
if (memcmp(in->hash, hash, sizeof(hash)) != 0) {
fprintf(stderr, "%s %d: invalid ciphertext\n", __FILE__, __LINE__);
return -1;
}
return 1;
}
int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *C, uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (!C) {
return 0;
}
if (asn1_integer_to_der(C->point.x, 32, NULL, &len) != 1
|| asn1_integer_to_der(C->point.y, 32, NULL, &len) != 1
|| asn1_octet_string_to_der(C->hash, 32, NULL, &len) != 1
|| asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_integer_to_der(C->point.x, 32, out, outlen) != 1
|| asn1_integer_to_der(C->point.y, 32, out, outlen) != 1
|| asn1_octet_string_to_der(C->hash, 32, out, outlen) != 1
|| asn1_octet_string_to_der(C->ciphertext, C->ciphertext_size, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_ciphertext_from_der(SM2_CIPHERTEXT *C, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
const uint8_t *x;
const uint8_t *y;
const uint8_t *hash;
const uint8_t *c;
size_t xlen, ylen, hashlen, clen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_integer_from_der(&x, &xlen, &d, &dlen) != 1
|| asn1_integer_from_der(&y, &ylen, &d, &dlen) != 1
|| asn1_octet_string_from_der(&hash, &hashlen, &d, &dlen) != 1
|| asn1_octet_string_from_der(&c, &clen, &d, &dlen) != 1
|| asn1_length_le(xlen, 32) != 1
|| asn1_length_le(ylen, 32) != 1
|| asn1_check(hashlen == 32) != 1
|| asn1_length_le(clen, SM2_MAX_PLAINTEXT_SIZE) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
memset(C, 0, sizeof(SM2_CIPHERTEXT));
memcpy(C->point.x + 32 - xlen, x, xlen);
memcpy(C->point.y + 32 - ylen, y, ylen);
if (sm2_point_is_on_curve(&C->point) != 1) {
error_print();
return -1;
}
memcpy(C->hash, hash, hashlen);
memcpy(C->ciphertext, c, clen);
C->ciphertext_size = (uint8_t)clen;
return 1;
}
int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
{
uint8_t buf[512] = {0};
SM2_CIPHERTEXT *c = (SM2_CIPHERTEXT *)buf;
int i;
if (sm2_ciphertext_from_der(c, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
format_bytes(fp, fmt, ind, "XCoordinate", c->point.x, 32);
format_bytes(fp, fmt, ind, "YCoordinate", c->point.y, 32);
format_bytes(fp, fmt, ind, "HASH", c->hash, 32);
format_bytes(fp, fmt, ind, "CipherText", c->ciphertext, c->ciphertext_size);
return 1;
}
int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM2_CIPHERTEXT C;
if (!key || !in || !out || !outlen) {
error_print();
return -1;
}
if (inlen < SM2_MIN_PLAINTEXT_SIZE || inlen > SM2_MAX_PLAINTEXT_SIZE) {
error_print();
return -1;
}
if (sm2_do_encrypt(key, in, inlen, &C) != 1) {
error_print();
return -1;
}
*outlen = 0;
if (sm2_ciphertext_to_der(&C, &out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM2_CIPHERTEXT C;
if (!key || !in || !out || !outlen) {
error_print();
return -1;
}
if (sm2_ciphertext_from_der(&C, &in, &inlen) != 1
|| asn1_length_is_zero(inlen) != 1) {
error_print();
return -1;
}
if (sm2_do_decrypt(key, &C, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out)
{
if (!key || !peer_public || !out) {
error_print();
return -1;
}
if (sm2_point_mul(out, key->private_key, peer_public) != 1) {
error_print();
return -1;
}
return 1;
}

View File

@@ -118,6 +118,10 @@ int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[16],
iv = in + inlen - 32;
}
sm4_cbc_decrypt(key, iv, in + inlen - 16, 1, block);
format_bytes(stderr, 0, 0, "last_decrypted_block", block, 16);
padding = block[15];
if (padding < 1 || padding > 16) {
error_print();
@@ -234,3 +238,145 @@ int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
}
return 1;
}
int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx,
const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE])
{
sm4_set_encrypt_key(&ctx->sm4_key, key);
memcpy(ctx->iv, iv, SM4_BLOCK_SIZE);
memset(ctx->block, 0, SM4_BLOCK_SIZE);
ctx->block_nbytes = 0;
return 1;
}
int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
size_t left;
size_t nblocks;
size_t len;
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print();
return -1;
}
*outlen = 0;
if (ctx->block_nbytes) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen < left) {
memcpy(ctx->block + ctx->block_nbytes, in, inlen);
ctx->block_nbytes += inlen;
return 1;
}
memcpy(ctx->block + ctx->block_nbytes, in, left);
sm4_cbc_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, 1, out);
memcpy(ctx->iv, out, SM4_BLOCK_SIZE);
in += left;
inlen -= left;
out += SM4_BLOCK_SIZE;
*outlen += SM4_BLOCK_SIZE;
}
if (inlen >= SM4_BLOCK_SIZE) {
nblocks = inlen / SM4_BLOCK_SIZE;
len = nblocks * SM4_BLOCK_SIZE;
sm4_cbc_encrypt(&ctx->sm4_key, ctx->iv, in, nblocks, out);
memcpy(ctx->iv, out + len - SM4_BLOCK_SIZE, SM4_BLOCK_SIZE);
in += len;
inlen -= len;
out += len;
*outlen += len;
}
if (inlen) {
memcpy(ctx->block, in, inlen);
}
ctx->block_nbytes = inlen;
return 1;
}
int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen)
{
size_t left;
size_t i;
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print();
return -1;
}
format_bytes(stderr, 0, 0, "encrypt_finish", ctx->block, ctx->block_nbytes);
if (sm4_cbc_padding_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, ctx->block_nbytes, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx,
const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE])
{
sm4_set_decrypt_key(&ctx->sm4_key, key);
memcpy(ctx->iv, iv, SM4_BLOCK_SIZE);
memset(ctx->block, 0, SM4_BLOCK_SIZE);
ctx->block_nbytes = 0;
return 1;
}
int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
size_t left, len, nblocks;
if (ctx->block_nbytes > SM4_BLOCK_SIZE) {
error_print();
return -1;
}
*outlen = 0;
if (ctx->block_nbytes < SM4_BLOCK_SIZE) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen <= left) {
memcpy(ctx->block + ctx->block_nbytes, in, inlen);
ctx->block_nbytes += inlen;
return 1;
}
memcpy(ctx->block + ctx->block_nbytes, in, left);
sm4_cbc_decrypt(&ctx->sm4_key, ctx->iv, ctx->block, 1, out);
memcpy(ctx->iv, ctx->block, SM4_BLOCK_SIZE);
in += left;
inlen -= left;
out += SM4_BLOCK_SIZE;
*outlen += SM4_BLOCK_SIZE;
}
if (inlen > SM4_BLOCK_SIZE) {
nblocks = (inlen-1) / SM4_BLOCK_SIZE;
len = nblocks * SM4_BLOCK_SIZE;
sm4_cbc_decrypt(&ctx->sm4_key, ctx->iv, in, nblocks, out);
memcpy(ctx->iv, in + len - SM4_BLOCK_SIZE, SM4_BLOCK_SIZE);
in += len;
inlen -= len;
out += len;
*outlen += len;
}
memcpy(ctx->block, in, inlen);
ctx->block_nbytes = inlen;
return 1;
}
int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen)
{
if (ctx->block_nbytes != SM4_BLOCK_SIZE) {
error_print();
return -1;
}
format_bytes(stderr, 0, 0, "block", ctx->block, ctx->block_nbytes);
format_bytes(stderr, 0, 0, "iv", ctx->iv, 16);
if (sm4_cbc_padding_decrypt(&ctx->sm4_key, ctx->iv, ctx->block, SM4_BLOCK_SIZE, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1544,6 +1544,7 @@ int tls_compression_methods_has_null_compression(const uint8_t *meths, size_t me
}
// FIXME: 设定支持的最大输入长度
// FIXME: 没回返回实际的发送长度
int tls_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen)
{
const SM3_HMAC_CTX *hmac_ctx;
@@ -1618,3 +1619,10 @@ int tls_shutdown(TLS_CONNECT *conn)
{
return -1;
}
// 参考 man verify 的错误返回值
int tls_get_verify_result(TLS_CONNECT *conn, int *result)
{
*result = 0;
return 1;
}

View File

@@ -52,6 +52,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
@@ -67,7 +68,6 @@
static const int tls12_ciphers[] = {
GMSSL_cipher_ecdhe_sm2_with_sm4_sm3,
};
@@ -258,27 +258,30 @@ int tls12_connect(TLS_CONNECT *conn, const char *hostname, int port,
uint8_t verify_data[12];
uint8_t remote_verify_data[12];
struct sockaddr_in server;
if (conn->sock <= 0) {
int sock;
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr(hostname);
server.sin_family = AF_INET;
server.sin_port = htons(port);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
error_print();
return -1;
}
if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) {
error_print();
return -1;
}
conn->sock = sock;
conn->is_client = 1;
}
sm3_init(&sm3_ctx);
server.sin_addr.s_addr = inet_addr(hostname);
server.sin_family = AF_INET;
server.sin_port = htons(port);
if ((conn->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
error_print();
return -1;
}
if (connect(conn->sock, (struct sockaddr *)&server , sizeof(server)) < 0) {
error_print();
return -1;
}
conn->is_client = 1;
if (client_certs_fp) {
if (!client_sign_key) {
error_print();
@@ -294,8 +297,6 @@ int tls12_connect(TLS_CONNECT *conn, const char *hostname, int port,
tls_record_set_version(finished, TLS_version_tls12);
tls_trace("send ClientHello\n");
tls_random_generate(client_random);
if (tls_record_set_handshake_client_hello(record, &recordlen,
@@ -595,15 +596,24 @@ int tls12_connect(TLS_CONNECT *conn, const char *hostname, int port,
return 1;
}
// 实际上我们需要好几个比较大的buffer
// 一个是记录的buffer
// 还有就是server端需要一个握手buffer这是啥?
/*
常规情况下服务器和客户端对所有的握手消息计算哈希值最后用于Finished消息
但是如果服务器要求客户端提供客户端证书,那么就必须要验证客户端证书
*/
int tls_set_fd(TLS_CONNECT *conn, int sock)
{
int opts;
if ((opts = fcntl(sock, F_GETFL)) < 0) {
error_print();
return -1;
}
opts &= ~O_NONBLOCK;
if (fcntl(sock, F_SETFL, opts) < 0) {
error_print();
return -1;
}
conn->sock = sock;
return 1;
}
int tls12_accept(TLS_CONNECT *conn, int port,
FILE *server_certs_fp, const SM2_KEY *server_sign_key,
@@ -641,40 +651,37 @@ int tls12_accept(TLS_CONNECT *conn, int port,
uint8_t local_verify_data[12];
size_t i;
int sock;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
socklen_t client_addrlen;
if (conn->sock <= 0) {
int sock;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
socklen_t client_addrlen;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
error_print();
return -1;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
error_print();
return -1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
error_print();
return -1;
}
error_puts("start listen ...");
listen(sock, 5);
client_addrlen = sizeof(client_addr);
if ((conn->sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) {
error_print();
return -1;
}
error_puts("connected\n");
conn->sock = sock;
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
error_print();
return -1;
}
error_puts("start listen ...");
listen(sock, 5);
memset(conn, 0, sizeof(*conn));
client_addrlen = sizeof(client_addr);
if ((conn->sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) {
error_print();
return -1;
}
error_puts("connected\n");
sm3_init(&sm3_ctx);
@@ -776,9 +783,11 @@ int tls12_accept(TLS_CONNECT *conn, int port,
if (client_cacerts_fp) {
tls_trace("send CertificateRequest\n");
const int cert_types[] = { TLS_cert_type_ecdsa_sign, };
uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0};
size_t cert_types_count = sizeof(cert_types)/sizeof(cert_types[0]);
uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0};
size_t ca_names_len = 0;
// FIXME: 没有设置ca_names
if (tls_record_set_handshake_certificate_request(record, &recordlen,
cert_types, cert_types_count,
ca_names, ca_names_len) != 1) {
@@ -835,6 +844,8 @@ int tls12_accept(TLS_CONNECT *conn, int port,
tls_array_to_bytes(record + 5, recordlen - 5, &handshakes, &handshakeslen);
}
//sleep(1);
tls_trace("recv ClientKeyExchange\n");
if (tls12_record_recv(record, &recordlen, conn->sock) != 1) {
error_print();

View File

@@ -405,7 +405,6 @@ int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
}
x509_attr_type_and_value_print(fp, fmt, ind, "AttributeTypeAndValue", p, len);
}
//format_print(fp, fmt, ind, "\n");
return 1;
}

View File

@@ -55,6 +55,7 @@
#include <gmssl/x509_crl.h>
#include <gmssl/x509_alg.h>
#include <gmssl/x509_ext.h>
#include <gmssl/pem.h>
#include <gmssl/error.h>
static const char *x509_crl_reason_names[] = {
@@ -180,6 +181,7 @@ int x509_crl_entry_exts_add_reason(uint8_t *exts, size_t *extslen, size_t maxlen
uint8_t *p = val;
size_t vlen = 0;
exts += *extslen;
if (x509_crl_reason_to_der(reason, &p, &vlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
@@ -199,6 +201,7 @@ int x509_crl_entry_exts_add_invalidity_date(uint8_t *exts, size_t *extslen, size
uint8_t *p = val;
size_t vlen = 0;
exts += *extslen;
if (asn1_generalized_time_to_der(tv, &p, &vlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
@@ -216,10 +219,71 @@ int x509_crl_entry_exts_add_certificate_issuer(uint8_t *exts, size_t *extslen, s
return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
}
int x509_crl_entry_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int ret, oid, critical;
const uint8_t *v;
size_t vlen;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (x509_crl_entry_ext_id_from_der(&oid, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "extnID: %s\n", x509_crl_entry_ext_id_name(oid));
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;
if (oid == OID_ce_crl_reasons) {
int reason;
if (x509_crl_reason_from_der(&reason, &v, &vlen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "reasonCode: %s\n", x509_crl_reason_name(reason));
} else if (oid == OID_ce_invalidity_date) {
time_t invalidity_date;
if (asn1_generalized_time_from_der(&invalidity_date, &v, &vlen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "invalidityDate: %s", ctime(&invalidity_date));
} else if (oid == OID_ce_certificate_issuer) {
const uint8_t *gns;
size_t gnslen;
if (asn1_sequence_from_der(&gns, &gnslen, &v, &vlen) != 1) {
error_print();
return -1;
}
x509_general_names_print(fp, fmt, ind, "certificateIssuer", gns, gnslen);
} else {
err:
error_print();
return -1;
}
return 1;
}
int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
error_print();
return -1;
const uint8_t *p;
size_t len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
while (dlen) {
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
error_print();
return -1;
}
x509_crl_entry_ext_print(fp, fmt, ind, "Extension", p, len);
}
return 1;
}
int x509_revoked_cert_to_der(
@@ -230,11 +294,11 @@ int x509_revoked_cert_to_der(
{
size_t len = 0;
if (asn1_integer_to_der(serial, serial_len, NULL, &len) != 1
|| asn1_generalized_time_to_der(revoke_date, NULL, &len) != 1
|| x509_time_to_der(revoke_date, NULL, &len) != 1
|| asn1_sequence_to_der(entry_exts, entry_exts_len, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_integer_to_der(serial, serial_len, out, outlen) != 1
|| asn1_generalized_time_to_der(revoke_date, out, outlen) != 1
|| x509_time_to_der(revoke_date, out, outlen) != 1
|| asn1_sequence_to_der(entry_exts, entry_exts_len, out, outlen) < 0) {
error_print();
return -1;
@@ -257,7 +321,7 @@ int x509_revoked_cert_from_der(
return ret;
}
if (asn1_integer_from_der(serial, serial_len, &d, &dlen) != 1
|| asn1_generalized_time_from_der(revoke_date, &d, &dlen) != 1
|| x509_time_from_der(revoke_date, &d, &dlen) != 1
|| asn1_sequence_from_der(entry_exts, entry_exts_len, &d, &dlen) < 0
|| asn1_length_is_zero(dlen) != 1) {
error_print();
@@ -278,10 +342,10 @@ int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const
if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err;
format_bytes(fp, fmt, ind, "userCertificate", p, len);
if (asn1_generalized_time_from_der(&tv, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "revocationDate: %s\n", ctime(&tv));
if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "revocationDate: %s", ctime(&tv));
if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err;
if (ret) x509_crl_entry_exts_print(fp, fmt, ind, "crlEntryExtensions", p, len); // 这里需要一个函数能够处理
if (ret) x509_crl_entry_exts_print(fp, fmt, ind, "crlEntryExtensions", p, len);
if (asn1_length_is_zero(dlen) != 1) goto err;
return 1;
err:
@@ -289,19 +353,60 @@ err:
return -1;
}
int x509_revoked_certs_add_revoked_cert(uint8_t *d, size_t *dlen, size_t maxlen,
const uint8_t *serial, size_t serial_len,
time_t revoke_date,
const uint8_t *entry_exts, size_t entry_exts_len)
{
error_print();
return -1;
}
int x509_revoked_certs_get_revoked_cert_by_serial_number(const uint8_t *d, size_t dlen,
const uint8_t *serial, size_t serial_len,
time_t *revoke_date,
const uint8_t **entry_exts, size_t *entry_exts_len)
{
error_print();
return -1;
}
int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *p;
size_t len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
while (dlen) {
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
error_print();
return -1;
}
x509_revoked_cert_print(fp, fmt, ind, "RevokedCertificate", p, len);
}
return 1;
}
static uint32_t oid_ce_authority_key_identifier[] = { oid_ce,35 };
static uint32_t oid_ce_issuer_alt_name[] = { oid_ce,18 };
static uint32_t oid_ce_crl_number[] = { oid_ce,20 };
static uint32_t oid_ce_delta_crl_indicator[] = { oid_ce,27 };
static uint32_t oid_ce_issuing_distribution_point[] = { oid_ce,28 };
static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 };
static uint32_t oid_pe_authority_info_access[] = { oid_pe,1 };
static const ASN1_OID_INFO x509_crl_exts[] = {
{ OID_ce_authority_key_identifier, "AuthorityKeyIdentifier", oid_ce_authority_key_identifier, sizeof(oid_ce_authority_key_identifier)/sizeof(int) },
{ OID_ce_issuer_alt_name, "IssuerAltName", oid_ce_issuer_alt_name, sizeof(oid_ce_issuer_alt_name)/sizeof(int) },
{ OID_ce_crl_number, "CRLNumber", oid_ce_crl_number, sizeof(oid_ce_crl_number)/sizeof(int) },
{ OID_ce_delta_crl_indicator, "DeltaCRLIndicator", oid_ce_delta_crl_indicator, sizeof(oid_ce_delta_crl_indicator)/sizeof(int) },
{ OID_ce_issuing_distribution_point, "IssuingDistributionPoint", oid_ce_issuing_distribution_point, sizeof(oid_ce_issuing_distribution_point)/sizeof(int) }
{ OID_ce_issuing_distribution_point, "IssuingDistributionPoint", oid_ce_issuing_distribution_point, sizeof(oid_ce_issuing_distribution_point)/sizeof(int) },
{ OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, sizeof(oid_ce_freshest_crl)/sizeof(int) },
{ OID_pe_authority_info_access, "AuthorityInfoAccess", oid_pe_authority_info_access, sizeof(oid_pe_authority_info_access)/sizeof(int) },
};
static const int x509_crl_exts_count =
@@ -367,8 +472,12 @@ int x509_crl_exts_add_authority_key_identifier(
const uint8_t *issuer, size_t issuer_len,
const uint8_t *serial, size_t serial_len)
{
error_print();
return -1;
if (x509_exts_add_authority_key_identifier(exts, extslen, maxlen, critical,
keyid, keyid_len, issuer, issuer_len, serial, serial_len) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_crl_exts_add_issuer_alt_name(
@@ -376,8 +485,11 @@ int x509_crl_exts_add_issuer_alt_name(
int critical,
const uint8_t *d, size_t dlen)
{
error_print();
return -1;
if (x509_exts_add_issuer_alt_name(exts, extslen, maxlen, critical, d, dlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_crl_exts_add_crl_number(
@@ -385,8 +497,21 @@ int x509_crl_exts_add_crl_number(
int critical,
int num)
{
error_print();
return -1;
int oid = OID_ce_crl_number;
size_t curlen = *extslen;
uint8_t val[32];
uint8_t *p = val;
size_t vlen = 0;
exts += *extslen;
if (asn1_int_to_der(num, &p, &vlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_crl_exts_add_delta_crl_indicator(
@@ -394,8 +519,21 @@ int x509_crl_exts_add_delta_crl_indicator(
int critical,
int num)
{
error_print();
return -1;
int oid = OID_ce_delta_crl_indicator;
size_t curlen = *extslen;
uint8_t val[32];
uint8_t *p = val;
size_t vlen = 0;
exts += *extslen;
if (asn1_int_to_der(num, &p, &vlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_crl_exts_add_issuing_distribution_point(
@@ -412,12 +550,158 @@ int x509_crl_exts_add_issuing_distribution_point(
return -1;
}
int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
int x509_issuing_distribution_point_to_der(
int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
int only_contains_user_certs,
int only_contains_ca_certs,
int only_some_reasons,
int indirect_crl,
int only_contains_attr_certs,
uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0
|| asn1_implicit_boolean_to_der(1, only_contains_user_certs, NULL, &len) < 0
|| asn1_implicit_boolean_to_der(2, only_contains_ca_certs, NULL, &len) < 0
|| asn1_implicit_bits_to_der(3, only_some_reasons, NULL, &len) < 0 // 是否有特化的类型
|| asn1_implicit_boolean_to_der(4, indirect_crl, NULL, &len) < 0
|| asn1_implicit_boolean_to_der(5, only_contains_attr_certs, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0
|| asn1_implicit_boolean_to_der(1, only_contains_user_certs, out, outlen) < 0
|| asn1_implicit_boolean_to_der(2, only_contains_ca_certs, out, outlen) < 0
|| asn1_implicit_bits_to_der(3, only_some_reasons, out, outlen) < 0 // 是否有特化的类型
|| asn1_implicit_boolean_to_der(4, indirect_crl, out, outlen) < 0
|| asn1_implicit_boolean_to_der(5, only_contains_attr_certs, out, outlen) < 0) {
error_print();
return -1;
}
return 1;
}
int x509_issuing_distribution_point_from_der(
int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len,
int *only_contains_user_certs,
int *only_contains_ca_certs,
int *only_some_reasons,
int *indirect_crl,
int *only_contains_attr_certs,
const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0
|| asn1_implicit_boolean_from_der(1, only_contains_user_certs, &d, &dlen) < 0
|| asn1_implicit_boolean_from_der(2, only_contains_ca_certs, &d, &dlen) < 0
|| asn1_implicit_bits_from_der(3, only_some_reasons, &d, &dlen) < 0
|| asn1_implicit_boolean_from_der(4, indirect_crl, &d, &dlen) < 0
|| asn1_implicit_boolean_from_der(5, only_contains_attr_certs, &d, &dlen) < 0
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *p;
size_t len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
error_print();
return -1;
}
int x509_access_descriptions_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
error_print();
return -1;
}
int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int ret, oid, critical;
const char *name;
const uint8_t *v;
size_t vlen;
const uint8_t *p;
size_t len;
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 ((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;
switch (oid) {
case OID_ce_authority_key_identifier:
case OID_ce_issuer_alt_name:
case OID_ce_issuing_distribution_point:
case OID_ce_freshest_crl:
case OID_pe_authority_info_access:
if (asn1_sequence_from_der(&p, &len, &v, &vlen) != 1) {
error_print();
return -1;
}
break;
case OID_ce_crl_number:
case OID_ce_delta_crl_indicator:
if (asn1_int_from_der(&num, &v, &vlen) != 1) {
error_print();
return -1;
}
break;
}
name = x509_crl_ext_id_name(oid);
switch (oid) {
case OID_ce_authority_key_identifier: x509_authority_key_identifier_print(fp, fmt, ind, name, p, len); break;
case OID_ce_issuer_alt_name: x509_general_names_print(fp, fmt, ind, name, p, len); break;
case OID_ce_crl_number: format_print(fp, fmt, ind, "%s: %d\n", name, num); break;
case OID_ce_delta_crl_indicator: format_print(fp, fmt, ind, "%s: %d\n", name, num); break;
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;
}
if (asn1_length_is_zero(vlen) != 1) goto err;
return 1;
err:
error_print();
return -1;
}
int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *p;
size_t len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
while (dlen) {
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
error_print();
return -1;
}
x509_crl_ext_print(fp, fmt, ind, "Extension", p, len);
}
return 1;
}
int x509_tbs_crl_to_der(
int version,
int signature_algor,
@@ -429,16 +713,16 @@ int x509_tbs_crl_to_der(
{
size_t len = 0;
if (asn1_int_to_der(version, NULL, &len) < 0
|| x509_signature_algor_to_der(signature_algor, NULL, &len) < 0
|| asn1_sequence_to_der(issuer, issuer_len, NULL, &len) != 1
|| x509_signature_algor_to_der(signature_algor, NULL, &len) != 1
|| x509_name_to_der(issuer, issuer_len, NULL, &len) != 1
|| x509_time_to_der(this_update, NULL, &len) != 1
|| x509_time_to_der(next_update, NULL, &len) < 0
|| asn1_sequence_to_der(revoked_certs, revoked_certs_len, NULL, &len) < 0
|| asn1_sequence_to_der(exts, exts_len, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(version, out, outlen) < 0
|| x509_signature_algor_to_der(signature_algor, out, outlen) < 0
|| asn1_sequence_to_der(issuer, issuer_len, out, outlen) != 1
|| x509_signature_algor_to_der(signature_algor, out, outlen) != 1
|| x509_name_to_der(issuer, issuer_len, out, outlen) != 1
|| x509_time_to_der(this_update, out, outlen) != 1
|| x509_time_to_der(next_update, out, outlen) < 0
|| asn1_sequence_to_der(revoked_certs, revoked_certs_len, out, outlen) < 0
@@ -457,14 +741,72 @@ int x509_tbs_crl_from_der(
time_t *next_update,
const uint8_t **revoked_certs, size_t *revoked_certs_len,
const uint8_t **exts, size_t *exts_len,
uint8_t **in, size_t *inlen)
const uint8_t **in, size_t *inlen)
{
error_print();
return -1;
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_int_from_der(version, &d, &dlen) < 0
|| x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1
|| x509_name_from_der(issuer, issuer_len, &d, &dlen) != 1
|| x509_time_from_der(this_update, &d, &dlen) != 1
|| x509_time_from_der(next_update, &d, &dlen) < 0
|| asn1_sequence_from_der(revoked_certs, revoked_certs_len, &d, &dlen) < 0
|| x509_explicit_exts_from_der(0, exts, exts_len, &d, &dlen) < 0
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
if (*version >= 0 && *version != X509_version_v2) {
error_print();
return -1;
}
if (*revoked_certs && *version != X509_version_v2) {
error_print();
return -1;
}
if (*exts && *version != X509_version_v2) {
error_print();
return -1;
}
return 1;
}
int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int ret, val;
const uint8_t *p;
size_t len;
time_t tv;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err;
if (ret) format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(val), val);
if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "signature: %s\n", x509_signature_algor_name(val));
if (x509_name_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_name_print(fp, fmt, ind, "issuer", p, len);
if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "thisUpdate: %s", ctime(&tv));
if ((ret = x509_time_from_der(&tv, &d, &dlen)) < 0) goto err;
if (ret) format_print(fp, fmt, ind, "nextUpdate: %s", ctime(&tv));
if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err;
if (ret) x509_revoked_certs_print(fp, fmt, ind, "revokedCertificates", p, len);
if ((ret = x509_explicit_exts_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
if (ret) {
x509_crl_exts_print(fp, fmt, ind, "crlExtensions", p, len);
}
if (asn1_length_is_zero(dlen) != 1) goto err;
return 1;
err:
error_print();
return -1;
}
@@ -473,36 +815,105 @@ int x509_cert_list_to_der(const uint8_t *tbs_crl, size_t tbs_crl_len,
int signature_algor, const uint8_t *sig, size_t siglen,
uint8_t **out, size_t *outlen)
{
error_print();
return -1;
size_t len = 0;
if (asn1_sequence_to_der(tbs_crl, tbs_crl_len, NULL, &len) != 1
|| x509_signature_algor_to_der(signature_algor, NULL, &len) != 1
|| asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_sequence_to_der(tbs_crl, tbs_crl_len, out, outlen) != 1
|| x509_signature_algor_to_der(signature_algor, out, outlen) != 1
|| asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_cert_list_from_der(const uint8_t **tbs_crl, size_t *tbs_crl_len,
int *signature_algor, const uint8_t **sig, size_t *siglen,
const uint8_t **in, size_t *inlen)
{
error_print();
return -1;
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_sequence_from_der(tbs_crl, tbs_crl_len, &d, &dlen) != 1
|| x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1
|| asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int val;
const uint8_t *p;
size_t len;
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_tbs_crl_print(fp, fmt, ind, "tbsCertList", p, len);
if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val));
if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
format_bytes(fp, fmt, ind, "signatureValue", p, len);
if (asn1_length_is_zero(dlen) != 1) goto err;
return 1;
err:
error_print();
return -1;
}
int x509_crl_to_pem(const uint8_t *a, size_t *alen, FILE *fp)
// 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 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 x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp)
{
if (pem_write(fp, "X509 CRL", a, alen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp)
{
int ret;
if ((ret = pem_read(fp, "X509 CRL", a, alen, maxlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
return 1;
}
int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
{
const uint8_t *d;
size_t dlen;
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) {
error_print();
return -1;
}
x509_cert_list_print(fp, fmt, ind, label, d, dlen);
return 1;
}
@@ -553,31 +964,142 @@ int x509_tbs_crl_sign(
}
int x509_crl_verify(const uint8_t *a, size_t alen,
const SM2_KEY *signer_key, const char *signer_id, size_t signer_id_len)
const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len)
{
error_print();
return -1;
int ret;
const uint8_t *tbs;
size_t tbslen;
int sig_alg;
const uint8_t *sig;
size_t siglen;
SM2_SIGN_CTX verify_ctx;
if (x509_cert_list_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
if (sig_alg != OID_sm2sign_with_sm3) {
error_print();
return -1;
}
if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1
|| sm2_verify_update(&verify_ctx, tbs, tbslen) != 1
|| (ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) {
error_print();
return -1;
}
if (!ret) error_print();
return ret;
}
int x509_crl_get_details(const uint8_t *crl, size_t crl_len,
int *version,
const uint8_t **issuer, size_t *issuer_len,
time_t *this_update,
time_t *next_update,
const uint8_t **revoked_certs, size_t *revoked_certs_len,
int *signature_algor,
const uint8_t *sig, size_t *siglen)
int *opt_version,
const uint8_t **opt_issuer, size_t *opt_issuer_len,
time_t *opt_this_update,
time_t *opt_next_update,
const uint8_t **opt_revoked_certs, size_t *opt_revoked_certs_len,
const uint8_t **opt_exts, size_t *opt_exts_len,
int *opt_signature_algor,
const uint8_t **opt_sig, size_t *opt_siglen)
{
error_print();
return -1;
const uint8_t *tbs;
size_t tbs_len;
int signature_algor;
const uint8_t *sig;
size_t siglen;
if (x509_cert_list_from_der(&tbs, &tbs_len, &signature_algor, &sig, &siglen, &crl, &crl_len) != 1
|| asn1_length_is_zero(crl_len) != 1) {
error_print();
return -1;
}
if (opt_signature_algor) *opt_signature_algor = signature_algor;
if (opt_sig) *opt_sig = sig;
if (opt_siglen) *opt_siglen = siglen;
if (opt_version
|| opt_issuer || opt_issuer_len
|| opt_this_update
|| opt_next_update
|| opt_revoked_certs || opt_revoked_certs_len) {
int version;
int sig_alg;
const uint8_t *issuer;
size_t issuer_len;
time_t this_update;
time_t next_update;
const uint8_t *revoked_certs;
size_t revoked_certs_len;
const uint8_t *exts;
size_t exts_len;
if (x509_tbs_crl_from_der(
&version,
&sig_alg,
&issuer, &issuer_len,
&this_update,
&next_update,
&revoked_certs, &revoked_certs_len,
&exts, &exts_len,
&tbs, &tbs_len) != 1
|| asn1_length_is_zero(tbs_len) != 1) {
error_print();
return -1;
}
if (sig_alg != signature_algor) {
error_print();
return -1;
}
if (opt_version) *opt_version = version;
if (opt_issuer) *opt_issuer = issuer;
if (opt_issuer_len) *opt_issuer_len = issuer_len;
if (opt_this_update) *opt_this_update = this_update;
if (opt_next_update) *opt_next_update = next_update;
if (opt_revoked_certs) *opt_revoked_certs = revoked_certs;
if (opt_revoked_certs_len) *opt_revoked_certs_len = revoked_certs_len;
if (opt_exts) *opt_exts = exts;
if (opt_exts_len) *opt_exts_len = exts_len;
}
return 1;
}
int x509_crl_get_revoked_cert_by_serial_number(const uint8_t *a, size_t alen,
int x509_crl_find_revoked_cert_by_serial_number(const uint8_t *a, size_t alen,
const uint8_t *serial, size_t serial_len,
time_t *revoke_date,
const uint8_t **entry_exts, size_t *entry_exts_len)
{
return 1;
const uint8_t *certs;
size_t certslen;
if (x509_crl_get_details(a, alen,
NULL, NULL, NULL, NULL, NULL,
&certs, &certslen,
NULL, NULL, NULL, NULL, NULL) != 1) {
error_print();
return -1;
}
while (certslen) {
const uint8_t *serial_number;
size_t serial_number_len;
if (x509_revoked_cert_from_der(
&serial_number, &serial_number_len,
revoke_date,
entry_exts, entry_exts_len,
&certs, &certslen) != 1) {
error_print();
return -1;
}
if (serial_number_len == serial_len
&& memcmp(serial_number, serial, serial_len) == 0) {
return 1;
}
}
return 0;
}
int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)

View File

@@ -1616,6 +1616,20 @@ int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t
return 1;
}
int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
{
// 注意要能够解决d == NULL的情况
error_print();
return -1;
}
int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
{
// 注意要能够解决d == NULL的情况
error_print();
return -1;
}
int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen)
{
format_print(fp, fmt, ind, "%s\n", label);
@@ -1631,21 +1645,16 @@ int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *l
}
int x509_distribution_point_to_der(
int dist_point_choice, const uint8_t *dist_point_d, size_t dist_point_dlen,
int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
uint8_t **out, size_t *outlen)
{
size_t len = 0;
const uint8_t *dist_point;
size_t dist_point_len = 0;
x509_distribution_point_name_to_der(dist_point_choice, dist_point_d, dist_point_dlen, NULL, &dist_point_len);
if (asn1_explicit_to_der(0, dist_point, dist_point_len, NULL, &len) < 0
if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0
|| asn1_implicit_bits_to_der(1, reasons, NULL, &len) < 0
|| asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_explicit_to_der(0, dist_point, dist_point_len, out, outlen) < 0
|| x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0
|| asn1_implicit_bits_to_der(1, reasons, out, outlen) < 0
|| asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, out, outlen) < 0) {
error_print();
@@ -1655,29 +1664,22 @@ int x509_distribution_point_to_der(
}
int x509_distribution_point_from_der(
int *dist_point_choice, const uint8_t **dist_point_d, size_t *dist_point_dlen,
int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len,
int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *p;
size_t len;
const uint8_t *dist_point;
size_t dist_point_len;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_explicit_from_der(0, &dist_point, &dist_point_len, &p, &len) < 0
|| asn1_implicit_bits_from_der(1, reasons, &p, &len) < 0
|| asn1_implicit_sequence_from_der(2, crl_issuer, crl_issuer_len, &p, &len) < 0
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (x509_distribution_point_name_from_der(dist_point_choice, dist_point_d, dist_point_dlen, &dist_point, &dist_point_len) != 1
|| asn1_length_is_zero(dist_point_len) != 1) {
if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0
|| asn1_implicit_bits_from_der(1, reasons, &d, &dlen) < 0
|| asn1_implicit_sequence_from_der(2, crl_issuer, crl_issuer_len, &d, &dlen) < 0
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}

View File

@@ -164,8 +164,10 @@ static uint32_t oid_ce_policy_constraints[] = { oid_ce,36 };
static uint32_t oid_ce_ext_key_usage[] = { oid_ce,37 };
static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 };
static uint32_t oid_ce_inhibit_any_policy[] = { oid_ce,54 };
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
static const size_t oid_ce_cnt = sizeof(oid_ce_subject_directory_attributes)/sizeof(int);
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 };
@@ -186,6 +188,9 @@ static const ASN1_OID_INFO x509_ext_ids[] = {
{ OID_ce_crl_distribution_points, "CRLDistributionPoints", oid_ce_crl_distribution_points, oid_ce_cnt },
{ OID_ce_inhibit_any_policy, "InhibitAnyPolicy", oid_ce_inhibit_any_policy, oid_ce_cnt },
{ OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, oid_ce_cnt },
{ 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_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) },