mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-13 08:23:50 +08:00
update
This commit is contained in:
@@ -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;
|
||||
|
||||
94
src/cms.c
94
src/cms.c
@@ -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:
|
||||
|
||||
81
src/hkdf.c
81
src/hkdf.c
@@ -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;
|
||||
}
|
||||
*/
|
||||
|
||||
46
src/pbkdf2.c
46
src/pbkdf2.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -61,5 +61,6 @@ int rand_bytes(uint8_t *buf, size_t len)
|
||||
return -1;
|
||||
}
|
||||
fread(buf, 1, len, fp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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
1241
src/sm2_alg.c
Normal file
File diff suppressed because it is too large
Load Diff
1669
src/sm2_algo.c
1669
src/sm2_algo.c
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
{
|
||||
619
src/sm2_lib.c
619
src/sm2_lib.c
@@ -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;
|
||||
}
|
||||
|
||||
146
src/sm4_modes.c
146
src/sm4_modes.c
@@ -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;
|
||||
}
|
||||
|
||||
1060
src/sm9_math.c
1060
src/sm9_math.c
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
131
src/tls12.c
131
src/tls12.c
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
612
src/x509_crl.c
612
src/x509_crl.c
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) },
|
||||
|
||||
Reference in New Issue
Block a user