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

View File

@@ -5,6 +5,8 @@ set(CMAKE_MACOSX_RPATH 1)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mrdrnd -mrdseed")
include_directories(include)
add_library(
@@ -35,14 +37,14 @@ add_library(
src/pkcs8.c
src/rand.c
src/rc4.c
# src/rdrand.c
src/rsa.c
src/sha1.c
src/sha256.c
src/sha512.c
src/sm2_algo.c
src/sm2_asn1.c
src/sm2_alg.c
src/sm2_key.c
src/sm2_lib.c
src/sm2_prn.c
src/sm3.c
src/sm3_hmac.c
src/sm4_common.c
@@ -70,6 +72,7 @@ add_library(
src/zuc_eia.c
)
SET_TARGET_PROPERTIES(gmssl PROPERTIES VERSION 3.0 SOVERSION 3)
@@ -82,11 +85,13 @@ add_executable (sm2encrypt tools/sm2encrypt.c)
add_executable (sm2decrypt tools/sm2decrypt.c)
add_executable (sm3 tools/sm3.c)
add_executable (sm3hmac tools/sm3hmac.c)
add_executable (reqgen tools/reqgen.c)
add_executable (reqparse tools/reqparse.c)
add_executable (sm4 tools/sm4.c)
add_executable (certgen tools/certgen.c)
add_executable (certparse tools/certparse.c)
add_executable (certverify tools/certverify.c)
add_executable (crlparse tools/crlparse.c)
add_executable (reqgen tools/reqgen.c)
add_executable (reqparse tools/reqparse.c)
add_executable (reqsign tools/reqsign.c)
add_executable (tlcp_client tools/tlcp_client.c)
add_executable (tlcp_server tools/tlcp_server.c)
@@ -102,12 +107,14 @@ target_link_libraries (sm2encrypt LINK_PUBLIC gmssl)
target_link_libraries (sm2decrypt LINK_PUBLIC gmssl)
target_link_libraries (sm3 LINK_PUBLIC gmssl)
target_link_libraries (sm3hmac LINK_PUBLIC gmssl)
target_link_libraries (sm4 LINK_PUBLIC gmssl)
target_link_libraries (reqgen LINK_PUBLIC gmssl)
target_link_libraries (reqparse LINK_PUBLIC gmssl)
target_link_libraries (reqsign LINK_PUBLIC gmssl)
target_link_libraries (certgen LINK_PUBLIC gmssl)
target_link_libraries (certparse LINK_PUBLIC gmssl)
target_link_libraries (certverify LINK_PUBLIC gmssl)
target_link_libraries (crlparse LINK_PUBLIC gmssl)
target_link_libraries (tlcp_client LINK_PUBLIC gmssl)
target_link_libraries (tlcp_server LINK_PUBLIC gmssl)
target_link_libraries (tls12_client LINK_PUBLIC gmssl)
@@ -265,9 +272,9 @@ add_test(NAME x509_ext COMMAND x509_exttest)
add_test(NAME zuc COMMAND zuctest)
INSTALL(TARGETS sm3 sm3hmac sm2keygen sm2sign sm2verify sm2encrypt sm2decrypt RUNTIME DESTINATION bin)
INSTALL(TARGETS sm3 sm3hmac sm4 sm2keygen sm2sign sm2verify sm2encrypt sm2decrypt RUNTIME DESTINATION bin)
INSTALL(TARGETS certparse certgen certverify reqgen reqparse reqsign RUNTIME DESTINATION bin)
INSTALL(TARGETS tlcp_client tlcp_server tls12_client tls12_server tls13_client tls13_server RUNTIME DESTINATION bin)
INSTALL(TARGETS tlcp_client tlcp_server tls12_client tls12_server RUNTIME DESTINATION bin)
INSTALL(TARGETS gmssl LIBRARY DESTINATION lib)
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/gmssl DESTINATION include)

View File

@@ -268,6 +268,8 @@ int asn1_generalized_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, s
int asn1_header_to_der(int tag, size_t dlen, uint8_t **out, size_t *outlen);
#define asn1_implicit_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
#define asn1_octet_string_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_OCTET_STRING,dlen,out,outlen)
#define asn1_sequence_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SEQUENCE,dlen,out,outlen)
#define asn1_implicit_sequence_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)

View File

@@ -262,7 +262,6 @@ int cms_signer_infos_add_signer_info(
const uint8_t *serial_number, size_t serial_number_len,
const uint8_t *authed_attrs, size_t authed_attrs_len,
const uint8_t *unauthed_attrs, size_t unauthed_attrs_len);
#define cms_signer_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen)
#define cms_signer_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen)
int cms_signer_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
@@ -308,18 +307,19 @@ typedef struct {
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, // 当OID_cms_data时为raw data
const uint8_t *crls, size_t crls_len, // 可以为空
uint8_t **out, size_t *outlen);
int cms_signed_data_verify_from_der(
const uint8_t *extra_certs, size_t extra_certs_len,
const uint8_t *extra_crls, size_t extra_crls_len,
int *content_type, const uint8_t **content, size_t *content_len,
int *content_type, const uint8_t **content, size_t *content_len, // 是否应该返回raw data呢
const uint8_t **certs, size_t *certs_len,
const uint8_t **crls, size_t *crls_len,
const uint8_t **signer_infos, size_t *signer_infos_len,
const uint8_t **in, size_t *inlen);
/*
RecipientInfo ::= SEQUENCE {
version INTEGER (1),
@@ -344,6 +344,7 @@ int cms_recipient_info_from_der(
const uint8_t **in, size_t *inlen);
int cms_recipient_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int cms_recipient_info_encrypt_to_der(
const SM2_KEY *public_key,
const uint8_t *issuer, size_t issuer_len,
@@ -357,6 +358,12 @@ int cms_recipient_info_decrypt_from_der(
uint8_t *out, size_t *outlen, size_t maxlen,
const uint8_t **in, size_t *inlen);
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);
#define cms_recipient_infos_to_der(d,dlen,out,outlen) asn1_set_to_der(d,dlen,out,outlen)
#define cms_recipient_infos_from_der(d,dlen,in,inlen) asn1_set_from_der(d,dlen,in,inlen)
int cms_recipient_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);

75
include/gmssl/engine.h Normal file
View File

@@ -0,0 +1,75 @@
/*
* 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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GMSSL_ENGINE_H
#define GMSSL_ENGINE_H
#include <string.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int engine_init(void);
int engine_get_sign_key(int index);
int engine_sm2_sign();
int engine_rand_bytes();
int engine_info_print();
int engine_exit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -68,6 +68,14 @@ int hkdf_expand(const DIGEST *digest, const uint8_t *prk, size_t prklen,
const uint8_t *opt_info, size_t opt_infolen,
size_t L, uint8_t *okm);
int sm3_hkdf_extract(const uint8_t *salt, size_t saltlen,
const uint8_t *ikm, size_t ikmlen,
uint8_t *prk, size_t *prklen);
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);
#ifdef __cplusplus
}

View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved.
*
OCSPSigning * Redistribution and use in source and binary forms, with or without

View File

@@ -57,8 +57,12 @@
extern "C" {
#endif
int rand_bytes(uint8_t *buf, size_t buflen);
int rdrand_bytes(uint8_t *buf, size_t buflen);
int rdseed_bytes(uint8_t *buf, size_t buflen);
#ifdef __cplusplus
}

View File

@@ -60,6 +60,126 @@ extern "C" {
#endif
// 比较重要的是哪些是公开接口,公开接口应该做完整的参数检查
typedef uint64_t SM2_BN[8];
int sm2_bn_is_zero(const SM2_BN a);
int sm2_bn_is_one(const SM2_BN a);
int sm2_bn_is_odd(const SM2_BN a);
int sm2_bn_cmp(const SM2_BN a, const SM2_BN b);
int sm2_bn_from_hex(SM2_BN r, const char hex[64]);
int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen);
int sm2_bn_equ_hex(const SM2_BN a, const char *hex);
int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a);
void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]);
void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]);
void sm2_bn_to_hex(const SM2_BN a, char hex[64]);
void sm2_bn_to_bits(const SM2_BN a, char bits[256]);
void sm2_bn_set_word(SM2_BN r, uint32_t a);
void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b);
void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b);
void sm2_bn_rand_range(SM2_BN r, const SM2_BN range); // 这个函数需要修改一下,从外部引入随机数
#define sm2_bn_init(r) memset((r),0,sizeof(SM2_BN))
#define sm2_bn_set_zero(r) memset((r),0,sizeof(SM2_BN))
#define sm2_bn_set_one(r) sm2_bn_set_word((r),1)
#define sm2_bn_copy(r,a) memcpy((r),(a),sizeof(SM2_BN))
#define sm2_bn_clean(r) memset((r),0,sizeof(SM2_BN))
// GF(p)
typedef SM2_BN SM2_Fp;
void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b);
void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e);
void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a);
void sm2_fp_tri(SM2_Fp r, const SM2_Fp a);
void sm2_fp_div2(SM2_Fp r, const SM2_Fp a);
void sm2_fp_neg(SM2_Fp r, const SM2_Fp a);
void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a);
void sm2_fp_inv(SM2_Fp r, const SM2_Fp a);
void sm2_fp_rand(SM2_Fp r); // 外部提供随机性,如果满足条件就输出,如果不满足条件就哈希一下再输出
#define sm2_fp_init(r) sm2_bn_init(r)
#define sm2_fp_set_zero(r) sm2_bn_set_zero(r)
#define sm2_fp_set_one(r) sm2_bn_set_one(r)
#define sm2_fp_copy(r,a) sm2_bn_copy(r,a)
#define sm2_fp_clean(r) sm2_bn_clean(r)
// GF(n)
typedef SM2_BN SM2_Fn;
void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
void sm2_fn_mul(SM2_Fn r, const SM2_Fn a, const SM2_Fn b);
void sm2_fn_exp(SM2_Fn r, const SM2_Fn a, const SM2_Fn e);
void sm2_fn_neg(SM2_Fn r, const SM2_Fn a);
void sm2_fn_sqr(SM2_Fn r, const SM2_Fn a);
void sm2_fn_inv(SM2_Fn r, const SM2_Fn a);
void sm2_fn_rand(SM2_Fn r);
#define sm2_fn_init(r) sm2_bn_init(r)
#define sm2_fn_set_zero(r) sm2_bn_set_zero(r)
#define sm2_fn_set_one(r) sm2_bn_set_one(r)
#define sm2_fn_copy(r,a) sm2_bn_copy(r,a)
#define sm2_fn_clean(r) sm2_bn_clean(r)
typedef struct {
SM2_BN X;
SM2_BN Y;
SM2_BN Z;
} SM2_JACOBIAN_POINT;
void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R);
void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y); // 应该返回错误
void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y);
void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P);
void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P);
void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q);
void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q);
void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P);
void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]);
void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]);
void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k);
void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s); // 应该返回错误
void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]); // 应该返回错误
int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P);
int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P);
int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]);
int sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P);
#define sm2_jacobian_point_set_infinity(R) sm2_jacobian_point_init(R)
#define sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(SM2_JACOBIAN_POINT))
/*
SM2 Public API
SM2接口有两个层次基本的和ASN.1/PKI的
基本的接口不依赖ASN.1编码,可以直接将结构体的内存输出(endian一致即可)
基本的接口也不进行输入的格式检查,调用方应保证输入不为空
*/
// 这里应该用#define 给出常量的值
extern const SM2_BN SM2_P;
//extern const SM2_BN SM2_A;
extern const SM2_BN SM2_B;
extern const SM2_BN SM2_N;
extern const SM2_BN SM2_ONE;
extern const SM2_BN SM2_TWO;
extern const SM2_BN SM2_THREE;
extern const SM2_BN SM2_U_PLUS_ONE;
extern const SM2_JACOBIAN_POINT *SM2_G; // 应该同时给出Affine的
typedef struct {
uint8_t x[32];
uint8_t y[32];
@@ -69,13 +189,6 @@ void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]);
void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]);
int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen);
/*
RFC 5480 Elliptic Curve Cryptography Subject Public Key Information
ECPoint ::= OCTET STRING
*/
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen);
int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen);
int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y);
int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]);
@@ -83,8 +196,17 @@ int sm2_point_is_on_curve(const SM2_POINT *P);
int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P);
int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]);
int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); // R = k * P + s * G
/*
RFC 5480 Elliptic Curve Cryptography Subject Public Key Information
ECPoint ::= OCTET STRING
*/
#define SM2_POINT_MAX_SIZE (2 + 65)
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen);
int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen);
int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P);
typedef struct {
SM2_POINT public_key;
uint8_t private_key[32];
@@ -96,9 +218,9 @@ int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // 自动
int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key);
int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key);
int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key);
//int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // 这个函数的逻辑不清楚
int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]);
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key);
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key); // 和private_key_print参数不一致
/*
from RFC 5915
@@ -120,8 +242,8 @@ ECParameters ::= CHOICE { namedCurve OBJECT IDENTIFIER }
int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen);
int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen);
int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp);
int sm2_private_key_from_pem(SM2_KEY *key, FILE *fp);
//int sm2_private_key_to_pem(const SM2_KEY *key, FILE *fp);
//int sm2_private_key_from_pem(SM2_KEY *key, FILE *fp);
/*
AlgorithmIdentifier ::= {
@@ -159,8 +281,8 @@ enum {
int sm2_private_key_info_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen);
int sm2_private_key_info_from_der(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, const uint8_t **in, size_t *inlen);
int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp);
int sm2_private_key_info_from_pem(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, FILE *fp);
//int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp);
//int sm2_private_key_info_from_pem(SM2_KEY *key, const uint8_t **attrs, size_t *attrslen, FILE *fp);
/*
EncryptedPrivateKeyInfo ::= SEQUENCE {
@@ -180,31 +302,30 @@ typedef struct {
uint8_t s[32];
} SM2_SIGNATURE;
int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen);
int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen);
int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig);
#define SM2_MIN_SIGNATURE_SIZE 8
#define SM2_MAX_SIGNATURE_SIZE 72
int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen);
int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen);
int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
int sm2_verify(const SM2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen);
#define SM2_DEFAULT_ID "1234567812345678"
#define SM2_DEFAULT_ID_LENGTH (sizeof(SM2_DEFAULT_ID) - 1) // LENGTH for string and SIZE for bytes
#define SM2_DEFAULT_ID_BITS (SM2_DEFAULT_ID_LENGTH * 8)
#define SM2_MAX_ID_BITS 65535
#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8)
#define SM2_DEFAULT_ID "1234567812345678"
#define SM2_DEFAULT_ID_LENGTH (sizeof(SM2_DEFAULT_ID) - 1) // LENGTH for string and SIZE for bytes
#define SM2_DEFAULT_ID_BITS (SM2_DEFAULT_ID_LENGTH * 8)
#define SM2_MAX_ID_BITS 65535
#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8)
int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen);
typedef struct {
SM2_KEY key;
SM3_CTX sm3_ctx;
SM2_KEY key;
} SM2_SIGN_CTX;
int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
@@ -232,22 +353,20 @@ typedef struct {
uint8_t ciphertext[SM2_MAX_PLAINTEXT_SIZE];
} SM2_CIPHERTEXT;
int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen);
int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen);
int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out);
int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen);
#define SM2_MIN_CIPHERTEXT_SIZE 45 // dependes on SM2_MIN_PLAINTEXT_SIZE
#define SM2_MAX_CIPHERTEXT_SIZE 366 // depends on SM2_MAX_PLAINTEXT_SIZE
int sm2_ciphertext_to_der(const SM2_CIPHERTEXT *c, uint8_t **out, size_t *outlen);
int sm2_ciphertext_from_der(SM2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen);
int sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
int sm2_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out);
int sm2_selftest(void);
#ifdef __cplusplus
extern "C" {

View File

@@ -81,6 +81,7 @@ int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE]
int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[SM4_BLOCK_SIZE],
const uint8_t *in, size_t inlen, uint8_t *out);
#define sm4_ctr_decrypt(key,ctr,in,inlen,out) sm4_ctr_encrypt(key,ctr,in,inlen,out)
@@ -105,6 +106,24 @@ int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *tag, size_t taglen, uint8_t *out);
// Public API
typedef struct {
SM4_KEY sm4_key;
uint8_t iv[SM4_BLOCK_SIZE];
uint8_t block[SM4_BLOCK_SIZE];
size_t block_nbytes;
} SM4_CBC_CTX;
int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]);
int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen);
int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_BLOCK_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]);
int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen);
#ifdef __cplusplus
}
#endif

View File

@@ -367,61 +367,6 @@ typedef enum {
#define TLS_MAX_HANDSHAKES_SIZE 4096
// 应该保留对方的证书
// 我们应该讲这个值编码为一个标准的TLS的结构
typedef struct {
int is_client;
int version;
int cipher_suite;
int compression_method;
uint8_t master_secret[48];
uint8_t server_certs[1600];
size_t server_certs_size;
uint8_t client_cert[1024];
size_t client_cert_size;
} TLS_SESSION;
typedef struct {
int sock;
int is_client;
int version;
int cipher_suite;
uint8_t session_id[32];
size_t session_id_len;
uint8_t master_secret[48];
uint8_t key_block[96];
int do_trace;
uint8_t server_certs[TLS_MAX_CERTIFICATES_SIZE];
size_t server_certs_len;
uint8_t client_certs[TLS_MAX_CERTIFICATES_SIZE];
size_t client_certs_len;
SM3_HMAC_CTX client_write_mac_ctx;
SM3_HMAC_CTX server_write_mac_ctx;
SM4_KEY client_write_enc_key;
SM4_KEY server_write_enc_key;
uint8_t client_seq_num[8];
uint8_t server_seq_num[8];
uint8_t record[TLS_MAX_RECORD_SIZE];
uint8_t handshakes[TLS_MAX_HANDSHAKES_SIZE];
size_t handshakes_len;
uint8_t client_write_iv[12];
uint8_t server_write_iv[12];
BLOCK_CIPHER_KEY client_write_key;
BLOCK_CIPHER_KEY server_write_key;
} TLS_CONNECT;
@@ -430,32 +375,6 @@ typedef struct {
// 有可能在连接建立之后客户端还是想获得一些这个连接的有关信息呢比如random中有时间信息
// 服务器的证书一定是需要的吧
// 客户端证书应该是预置的
int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port,
FILE *ca_certs_fp, FILE *client_certs_fp, const SM2_KEY *client_sign_key);
int tlcp_accept(TLS_CONNECT *conn, int port,
FILE *server_certs_fp, const SM2_KEY *server_sign_key, const SM2_KEY *server_enc_key,
FILE *client_cacerts_fp, uint8_t *client_cert_verify_buf, size_t client_cert_verify_buflen);
int tls_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen);
int tls_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen);
int tls_seq_num_incr(uint8_t seq_num[8]);
@@ -541,6 +460,7 @@ int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen,
const uint8_t *certs, size_t certslen);
int tls_record_set_handshake_certificate_from_pem(uint8_t *record, size_t *recordlen, FILE *fp);
int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen);
int tls_certificate_get_subject_names(const uint8_t *certs, size_t certslen, uint8_t *names, size_t *nameslen);
int tls_certificate_get_public_keys(const uint8_t *certs, size_t certslen, SM2_KEY *sign_key, SM2_KEY *enc_key);
int tls_certificate_print(FILE *fp, const uint8_t *certs, size_t certslen, int format, int indent);
@@ -657,6 +577,113 @@ int tls_client_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t da
int tls12_record_recv(uint8_t *record, size_t *recordlen, int sock);
typedef struct {
int protocol_versions[4];
size_t protocol_versions_cnt;
int cipher_suites[8];
size_t cipher_suits_cnt;
uint8_t certs[4096];
size_t certslen;
SM2_KEY key;
SM2_KEY ex_key;
uint8_t cacerts[2048];
size_t cacertslen;
int shutdown_mode;
} TLS_CTX;
int tls_ctx_set_protocol_versions(TLS_CTX *ctx, const int *versions, size_t versions_cnt);
int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const char *ciphers);
int tls_ctx_set_certificats_and_keys(TLS_CTX *ctx, FILE *certs_fp, FILE *key_fp, const char *pass, FILE *ex_key_fp, const char *ex_pass);
int tls_ctx_set_ca_certificates(TLS_CTX *ctx, FILE *fp, int depth);
int tls_ctx_set_crl(TLS_CTX *ctx, FILE *fp);
int tls_ctx_set_client_verify_ca_certificates(TLS_CTX *ctx, FILE *fp, int depth);
int tls_ctx_set_shutdown_mode(TLS_CTX *ctx, int mode);
typedef struct {
int version;
int cipher_suite;
uint8_t session_id[32];
size_t session_id_len;
uint8_t peer_certs[1600];
size_t peer_certs_len;
uint8_t master_secret[48];
int client_cert_verify_result;
time_t start_time;
int timeout_secs;
} TLS_SESSION;
typedef struct {
int sock;
int is_client;
int version;
int cipher_suite;
uint8_t session_id[32];
size_t session_id_len;
uint8_t server_certs[TLS_MAX_CERTIFICATES_SIZE]; //
size_t server_certs_len;
uint8_t client_certs[TLS_MAX_CERTIFICATES_SIZE];
size_t client_certs_len;
int client_cert_verify_result;
uint8_t master_secret[48];
SM3_HMAC_CTX client_write_mac_ctx;
SM3_HMAC_CTX server_write_mac_ctx;
SM4_KEY client_write_enc_key;
SM4_KEY server_write_enc_key;
uint8_t client_seq_num[8];
uint8_t server_seq_num[8];
uint8_t key_block[96]; // 这个似乎不应该放在这里
BLOCK_CIPHER_KEY client_write_key; // used in tls13.c
BLOCK_CIPHER_KEY server_write_key; // used in tls13.c
uint8_t client_write_iv[12]; // 同样
uint8_t server_write_iv[12];
uint8_t record[TLS_MAX_RECORD_SIZE];
uint8_t handshakes[TLS_MAX_HANDSHAKES_SIZE];
size_t handshakes_len;
int do_trace;
} TLS_CONNECT;
int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx);
int tls_set_fd(TLS_CONNECT *conn, int sock);
int tls_get_verify_result(TLS_CONNECT *conn, int *result);
// 客户端证书应该是预置的
int tlcp_connect(TLS_CONNECT *conn, const char *hostname, int port,
FILE *ca_certs_fp, FILE *client_certs_fp, const SM2_KEY *client_sign_key);
int tlcp_accept(TLS_CONNECT *conn, int port,
FILE *server_certs_fp, const SM2_KEY *server_sign_key, const SM2_KEY *server_enc_key,
FILE *client_cacerts_fp, uint8_t *client_cert_verify_buf, size_t client_cert_verify_buflen);
int tls_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen);
int tls_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen); // 发送、接收的数据量以单独的接口提供
int tls12_connect(TLS_CONNECT *conn, const char *hostname, int port,
FILE *ca_certs_fp, FILE *client_certs_fp, const SM2_KEY *client_sign_key);
@@ -685,7 +712,6 @@ int tls_secrets_print(FILE *fp,
int format, int indent);
int tls_ext_signature_algors_to_bytes(const int *algors, size_t algors_count,
uint8_t **out, size_t *outlen);

View File

@@ -154,6 +154,8 @@ int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen,
const char *country, const char *state, const char *locality,
const char *org, const char *org_unit, const char *common_name);
#define x509_name_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_name_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_name_get_printable(const uint8_t *d, size_t dlen, char *str, size_t maxlen);
int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen);

View File

@@ -100,7 +100,6 @@ int x509_crl_entry_exts_add_certificate_issuer(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
const uint8_t *d, size_t dlen);
#define x509_crl_entry_exts_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_crl_entry_exts_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
@@ -151,6 +150,34 @@ int x509_crl_ext_id_from_name(const char *name);
int x509_crl_ext_id_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_crl_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen);
/*
IssuingDistributionPoint ::= SEQUENCE {
distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,
onlyContainsUserCerts [1] IMPLICIT BOOLEAN DEFAULT FALSE,
onlyContainsCACerts [2] IMPLICIT BOOLEAN DEFAULT FALSE,
onlySomeReasons [3] IMPLICIT ReasonFlags OPTIONAL,
indirectCRL [4] IMPLICIT BOOLEAN DEFAULT FALSE,
onlyContainsAttributeCerts [5] IMPLICIT BOOLEAN DEFAULT FALSE }
*/
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);
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 x509_crl_exts_add_authority_key_identifier(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
@@ -211,7 +238,7 @@ 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);
int x509_tbs_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
@@ -229,8 +256,9 @@ int x509_cert_list_from_der(const uint8_t **tbs_crl, size_t *tbs_crl_len,
int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
// x509_crl_ functions
int x509_crl_to_pem(const uint8_t *a, size_t *alen, FILE *fp);
int x509_crl_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen);
int x509_crl_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen);
int x509_crl_to_pem(const uint8_t *a, size_t alen, FILE *fp);
int x509_crl_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp);
int x509_crl_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
@@ -252,9 +280,10 @@ int x509_crl_get_details(const uint8_t *crl, size_t crl_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,
int *signature_algor,
const uint8_t *sig, size_t *siglen);
int x509_crl_get_revoked_cert_by_serial_number(const uint8_t *a, size_t alen,
const uint8_t **sig, size_t *siglen);
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);

View File

@@ -502,6 +502,10 @@ int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dle
int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen);
int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen);
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);
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);
int x509_explicit_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
DistributionPoint ::= SEQUENCE {
distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1241
src/sm2_alg.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -164,8 +164,10 @@ static uint32_t oid_ce_policy_constraints[] = { oid_ce,36 };
static uint32_t oid_ce_ext_key_usage[] = { oid_ce,37 };
static uint32_t oid_ce_freshest_crl[] = { oid_ce,46 };
static uint32_t oid_ce_inhibit_any_policy[] = { oid_ce,54 };
static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; // crl_entry_ext
static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; // crl_entry_ext
static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; // crl_entry_ext
static const size_t oid_ce_cnt = sizeof(oid_ce_subject_directory_attributes)/sizeof(int);
static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 };
static uint32_t oid_cert_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 };
static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 };
@@ -186,6 +188,9 @@ static const ASN1_OID_INFO x509_ext_ids[] = {
{ OID_ce_crl_distribution_points, "CRLDistributionPoints", oid_ce_crl_distribution_points, oid_ce_cnt },
{ OID_ce_inhibit_any_policy, "InhibitAnyPolicy", oid_ce_inhibit_any_policy, oid_ce_cnt },
{ OID_ce_freshest_crl, "FreshestCRL", oid_ce_freshest_crl, oid_ce_cnt },
{ OID_ce_crl_reasons, "CRLReasons", oid_ce_crl_reasons, oid_ce_cnt },
{ OID_ce_invalidity_date, "InvalidityDate", oid_ce_invalidity_date, oid_ce_cnt },
{ OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, oid_ce_cnt },
{ OID_netscape_cert_comment, "NetscapeCertComment", oid_netscape_cert_comment, sizeof(oid_netscape_cert_comment)/sizeof(int) },
{ OID_cert_authority_info_access, "CertificateAuthorityInformationAccess", oid_cert_authority_info_access, sizeof(oid_cert_authority_info_access)/sizeof(int) },
{ OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) },

View File

@@ -57,7 +57,6 @@
int test_aes(void)
{
int err = 0;
AES_KEY aes_key;
int i;
@@ -143,7 +142,7 @@ int test_aes(void)
aes_set_encrypt_key(&aes_key, key128, sizeof(key128));
if (memcmp(&aes_key, rk128, sizeof(rk128)) != 0) {
printf("failed\n");
err++;
return -1;
} else {
printf("ok\n");
}
@@ -152,7 +151,7 @@ int test_aes(void)
aes_set_encrypt_key(&aes_key, key192, sizeof(key192));
if (memcmp(&aes_key, rk192, sizeof(rk192)) != 0) {
printf("failed\n");
err++;
return -1;
} else {
printf("ok\n");
}
@@ -161,7 +160,7 @@ int test_aes(void)
aes_set_encrypt_key(&aes_key, key256, sizeof(key256));
if (memcmp(&aes_key, rk256, sizeof(rk256)) != 0) {
printf("failed\n");
err++;
return -1;
} else {
printf("ok\n");
}
@@ -171,7 +170,7 @@ int test_aes(void)
aes_encrypt(&aes_key, in1, buf);
if (memcmp(buf, out1, sizeof(out1)) != 0) {
printf("failed\n");
err++;
return -1;
} else {
printf("ok\n");
}
@@ -181,18 +180,17 @@ int test_aes(void)
aes_decrypt(&aes_key, buf, buf);
if (memcmp(buf, in1, sizeof(in1)) != 0) {
printf("failed\n");
err++;
return -1;
} else {
printf("ok\n");
}
return err;
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int test_aes_ctr(void)
{
int err = 0;
// NIST SP 800-38A F.5.1
char *hex_key = "2b7e151628aed2a6abf7158809cf4f3c";
char *hex_ctr = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
@@ -225,9 +223,9 @@ int test_aes_ctr(void)
printf("aes ctr test 1 ");
if (memcmp(buf, out, outlen) != 0) {
printf("failed\n");
err++;
format_bytes(stdout, 0, 0, "aes_ctr(msg) = ", buf, buflen);
format_bytes(stdout, 0, 0, " != ", out, outlen);
return -1;
} else {
printf("ok\n");
}
@@ -239,12 +237,13 @@ int test_aes_ctr(void)
printf("failed\n");
format_bytes(stdout, 0, 0, "msg = ", msg, msglen);
format_bytes(stdout, 0, 0, " = ", buf, buflen);
err++;
return -1;
} else {
printf("ok\n");
}
return err;
printf("%s() ok\n", __FUNCTION__);
return 1;
}
@@ -370,8 +369,6 @@ int test_aes_gcm(void)
int i;
for (i = 0; i < sizeof(aes_gcm_tests)/sizeof(aes_gcm_tests[0]); i++) {
int ok = 1;
hex_to_bytes(aes_gcm_tests[i].K, strlen(aes_gcm_tests[i].K), K, &Klen);
hex_to_bytes(aes_gcm_tests[i].P, strlen(aes_gcm_tests[i].P), P, &Plen);
hex_to_bytes(aes_gcm_tests[i].A, strlen(aes_gcm_tests[i].A), A, &Alen);
@@ -394,20 +391,24 @@ int test_aes_gcm(void)
format_bytes(stdout, 0, 2, " = ", out, Plen);
format_print(stdout, 0, 2, "T = %s\n", aes_gcm_tests[i].T);
format_bytes(stdout, 0, 2, " = ", tag, Tlen);
err++;
return -1;
} else {
printf("ok\n");
}
}
return err;
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
int err = 0;
err += test_aes();
err += test_aes_ctr();
err += test_aes_gcm();
return err;
if (test_aes() != 1) goto err;
if (test_aes_ctr() != 1) goto err;
if (test_aes_gcm() != 1) goto err;
printf("%s all tests passed!\n", __FILE__);
return 0;
err:
error_print();
return 1;
}

View File

@@ -92,7 +92,7 @@ static int test_cms_content_type(void)
(void)asn1_length_is_zero(len);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_content_info(void)
@@ -131,7 +131,7 @@ static int test_cms_content_info(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_enced_content_info(void)
@@ -189,7 +189,7 @@ static int test_cms_enced_content_info(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_enced_content_info_encrypt(void)
@@ -263,7 +263,7 @@ static int test_cms_enced_content_info_encrypt(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_issuer_and_serial_number(void)
@@ -313,7 +313,7 @@ static int test_cms_issuer_and_serial_number(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_signer_info(void)
@@ -394,53 +394,61 @@ static int test_cms_signer_info(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_signer_info_sign(void)
{
uint8_t buf[512];
uint8_t buf[1024];
uint8_t *p = buf;
const uint8_t *cp = buf;
size_t len = 0;
const uint8_t *d;
size_t dlen;
SM3_CTX sm3_ctx;
SM2_KEY sm2_key;
uint8_t issuer_buf[256];
size_t issuer_len;
uint8_t serial_buf[20];
uint8_t auth_attrs_buf[80];
// 这个函数的验证是需要证书的
uint8_t name[256];
size_t namelen;
time_t not_before, not_after;
uint8_t certs[1024];
size_t certslen;
SM3_CTX sm3_ctx;
const uint8_t *cert;
size_t certlen;
const uint8_t *issuer;
const uint8_t *serial;
size_t serial_len;
const uint8_t *issuer;
const uint8_t *auth_attrs;
size_t auth_attrs_len;
const uint8_t *unauth_attrs;
size_t unauth_attrs_len;
size_t serial_len, issuer_len, auth_attrs_len, unauth_attrs_len;
if (sm2_key_generate(&sm2_key) != 1
|| rand_bytes(serial_buf, sizeof(serial_buf)) != 1
|| x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1
|| time(&not_before) == -1
|| x509_validity_add_days(&not_after, not_before, 365) != 1
|| x509_cert_sign(certs, &certslen, sizeof(certs),
X509_version_v3, serial_buf, sizeof(serial_buf),
OID_sm2sign_with_sm3,
name, namelen,
not_before, not_after,
name, namelen,
&sm2_key, NULL, 0, NULL, 0, NULL, 0,
&sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return -1;
}
sm2_key_generate(&sm2_key);
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, (uint8_t *)"hello", 5);
x509_name_set(issuer_buf, &issuer_len, sizeof(issuer_buf), "CN", "Beijing", "Haidian", "PKU", "CS", "CA");
cp = p = buf; len = 0;
if (cms_signer_info_sign_to_der(
&sm3_ctx, &sm2_key,
issuer_buf, issuer_len,
serial_buf, sizeof(serial_buf),
NULL, 0,
NULL, 0,
name, namelen, serial_buf, sizeof(serial_buf),
NULL, 0, NULL, 0,
&p, &len) != 1
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
@@ -452,10 +460,8 @@ static int test_cms_signer_info_sign(void)
cp = p = buf; len = 0;
if (cms_signer_info_sign_to_der(
&sm3_ctx, &sm2_key,
issuer_buf, issuer_len,
serial_buf, sizeof(serial_buf),
NULL, 0,
NULL, 0,
name, namelen, serial_buf, sizeof(serial_buf),
NULL, 0, NULL, 0,
&p, &len) != 1
|| cms_signer_info_verify_from_der(
&sm3_ctx, certs, certslen,
@@ -471,7 +477,7 @@ static int test_cms_signer_info_sign(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_signer_infos(void)
@@ -530,7 +536,7 @@ static int test_cms_signer_infos(void)
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_digest_algors(void)
@@ -571,16 +577,381 @@ static int test_cms_digest_algors(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_cms_signed_data(void)
{
// 这个函数需要证书了,我们需要一个很容易生成证书的函数。
SM2_KEY sm2_key;
uint8_t cert[4096];
size_t certlen = 0;
CMS_CERTS_AND_KEY signers[1];
uint8_t data[48] = {0};
uint8_t buf[4096];
uint8_t *p = buf;
const uint8_t *cp = buf;
size_t len = 0;
const uint8_t *d;
size_t dlen;
return -1;
sm2_key_generate(&sm2_key);
{
uint8_t serial[20];
size_t serial_len = sizeof(serial);
uint8_t name[256];
size_t namelen = 0;
time_t not_before, not_after;
uint8_t subject[256];
size_t subject_len = 0;
uint8_t *p = cert;
const uint8_t *cp = cert;
rand_bytes(serial, sizeof(serial));
x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "CA");
time(&not_before);
x509_validity_add_days(&not_after, not_before, 365);
if (x509_cert_sign(
cert, &certlen, sizeof(cert),
X509_version_v3,
serial, sizeof(serial),
OID_sm2sign_with_sm3,
name, namelen,
not_before, not_after,
name, namelen,
&sm2_key,
NULL, 0,
NULL, 0,
NULL, 0,
&sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return -1;
}
}
signers[0].certs = cert;
signers[0].certs_len = certlen;
signers[0].sign_key = &sm2_key;
if (cms_signed_data_sign_to_der(
signers, sizeof(signers)/sizeof(signers[0]),
OID_cms_data, data, sizeof(data),
NULL, 0,
&p, &len) != 1
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
cms_signed_data_print(stderr, 0, 0, "SignedData", d, dlen);
cp = p = buf; len = 0;
{
int content_type;
const uint8_t *content;
size_t content_len;
const uint8_t *certs;
size_t certslen;
const uint8_t *crls;
size_t crlslen;
const uint8_t *signer_infos;
size_t signer_infos_len;
if (cms_signed_data_sign_to_der(
signers, sizeof(signers)/sizeof(signers[0]),
OID_cms_data, data, sizeof(data),
NULL, 0,
&p, &len) != 1
|| cms_signed_data_verify_from_der(
NULL, 0,
NULL, 0,
&content_type, &content, &content_len,
&certs, &certslen,
&crls, &crlslen,
&signer_infos, &signer_infos_len,
&cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_cms_recipient_info(void)
{
SM2_KEY sm2_key;
uint8_t name[256];
size_t namelen;
uint8_t serial_buf[20];
uint8_t in[16];
uint8_t buf[1024];
uint8_t *p = buf;
const uint8_t *cp = buf;
size_t len = 0;
const uint8_t *d;
size_t dlen;
int version;
const uint8_t *issuer;
size_t issuer_len;
const uint8_t *serial;
size_t serial_len;
int pke_algor;
const uint8_t *params;
size_t params_len;
const uint8_t *enced_key;
size_t enced_key_len;
uint8_t out[sizeof(in)];
size_t outlen;
sm2_key_generate(&sm2_key);
x509_name_set(name, &namelen, sizeof(name), "US", "CA", NULL, "BB", "AA", "CC");
rand_bytes(serial_buf, sizeof(serial_buf));
rand_bytes(in, sizeof(in));
if (cms_recipient_info_encrypt_to_der(&sm2_key,
name, namelen,
serial_buf, sizeof(serial_buf),
in, sizeof(in),
&p, &len) != 1
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
cms_recipient_info_print(stderr, 0, 0, "RecipientInfo", d, dlen);
cp = p = buf; len = 0;
if (cms_recipient_info_encrypt_to_der(&sm2_key,
name, namelen,
serial_buf, sizeof(serial_buf),
in, sizeof(in),
&p, &len) != 1
|| cms_recipient_info_from_der(
&version,
&issuer, &issuer_len,
&serial, &serial_len,
&pke_algor, &params, &params_len,
&enced_key, &enced_key_len,
&cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
cp = p = buf; len = 0;
if (cms_recipient_info_encrypt_to_der(
&sm2_key,
name, namelen,
serial_buf, sizeof(serial_buf),
in, sizeof(in),
&p, &len) != 1
|| cms_recipient_info_decrypt_from_der(
&sm2_key,
name, namelen,
serial_buf, sizeof(serial_buf),
out, &outlen, sizeof(out),
&cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (sizeof(in) != outlen
|| memcmp(in, out, outlen) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int test_cms_enveloped_data(void)
{
SM2_KEY sm2_key1;
uint8_t name1[256];
size_t name1_len;
uint8_t serial1[20];
size_t serial1_len;
SM2_KEY sm2_key2;
uint8_t name2[256];
size_t name2_len;
uint8_t serial2[20];
size_t serial2_len;
time_t not_before, not_after;
uint8_t certs[2048];
size_t certslen;
uint8_t key[16];
uint8_t iv[16];
uint8_t in[80];
uint8_t out[256];
size_t outlen;
size_t maxlen;
uint8_t buf[4096];
uint8_t *p;
const uint8_t *cp;
size_t len;
const uint8_t *d;
size_t dlen;
// prepare keys and certs
if (time(&not_before) == -1
|| x509_validity_add_days(&not_after, not_before, 365) != 1) {
error_print();
return -1;
}
p = certs;
certslen = 0;
maxlen = sizeof(certs);
if (sm2_key_generate(&sm2_key1) != 1
|| rand_bytes(serial1, sizeof(serial1)) != 1
|| x509_name_set(name1, &name1_len, sizeof(name1), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1
|| x509_cert_sign(
p, &len, maxlen,
X509_version_v3,
serial1, sizeof(serial1),
OID_sm2sign_with_sm3,
name1, name1_len,
not_before, not_after,
name1, name1_len,
&sm2_key1, NULL, 0, NULL, 0, NULL, 0,
&sm2_key1, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return -1;
}
p += len;
certslen += len;
maxlen -= len;
if (sm2_key_generate(&sm2_key2) != 1
|| rand_bytes(serial2, sizeof(serial2)) != 1
|| x509_name_set(name2, &name2_len, sizeof(name2), "CN", "Beijing", "Haidian", "PKU", "CS", "Bob") != 1
|| x509_cert_sign(
p, &len, maxlen,
X509_version_v3,
serial2, sizeof(serial2),
OID_sm2sign_with_sm3,
name2, name2_len,
not_before, not_after,
name2, name2_len,
&sm2_key2, NULL, 0, NULL, 0, NULL, 0,
&sm2_key2, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return -1;
}
p += len;
certslen += len;
maxlen -= len;
rand_bytes(key, sizeof(key));
rand_bytes(iv, sizeof(iv));
rand_bytes(in, sizeof(in));
// test
cp = p = buf; len = 0;
if (cms_enveloped_data_encrypt_to_der(
certs, certslen,
OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv),
OID_cms_data, in, sizeof(in),
NULL, 0, NULL, 0,
&p, &len) != 1
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
cms_enveloped_data_print(stderr, 0, 0, "EnvelopedData", d, dlen);
int content_type;
cp = p = buf; len = 0;
if (cms_enveloped_data_encrypt_to_der(
certs, certslen,
OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv),
OID_cms_data, in, sizeof(in),
NULL, 0, NULL, 0,
&p, &len) != 1) {
error_print();
return -1;
}
const uint8_t *rcpt_infos;
const uint8_t *shared_info1;
const uint8_t *shared_info2;
size_t rcpt_infos_len, shared_info1_len, shared_info2_len;
if (cms_enveloped_data_decrypt_from_der(
&sm2_key1,
name1, name1_len,
serial1, sizeof(serial1),
&content_type, out, &outlen,
&rcpt_infos, &rcpt_infos_len,
&shared_info1, &shared_info1_len,
&shared_info2, &shared_info2_len,
&cp, &len) != 1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_cms_signed_and_enveloped_data(void)
{
/*
444 int cms_signed_and_enveloped_data_encipher_to_der(
445 const CMS_CERTS_AND_KEY *signers, size_t signers_cnt,
446 const uint8_t *rcpt_certs, size_t rcpt_certs_len,
447 int enc_algor, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
448 int content_type, const uint8_t *content, size_t content_len,
449 const uint8_t *signers_crls, size_t signers_crls_len,
450 const uint8_t *shared_info1, size_t shared_info1_len,
451 const uint8_t *shared_info2, size_t shared_info2_len,
452 uint8_t **out, size_t *outlen);
453 int cms_signed_and_enveloped_data_decipher_from_der(
454 const SM2_KEY *rcpt_key,
455 const uint8_t *rcpt_issuer, size_t rcpt_issuer_len,
456 const uint8_t *rcpt_serial, size_t rcpt_serial_len,
457 int *content_type, uint8_t *content, size_t *content_len,
458 const uint8_t **prcpt_infos, size_t *prcpt_infos_len,
459 const uint8_t **shared_info1, size_t *shared_info1_len,
460 const uint8_t **shared_info2, size_t *shared_info2_len,
461 const uint8_t **certs, size_t *certs_len,
462 const uint8_t **crls, size_t *crls_len,
463 const uint8_t **psigner_infos, size_t *psigner_infos_len,
464 const uint8_t *extra_certs, size_t extra_certs_len,
465 const uint8_t *extra_crls, size_t extra_crls_len,
466 const uint8_t **in, size_t *inlen);
*/
SM2_KEY sign_key;
SM2_KEY decr_key;
uint8_t sign_serial[20];
uint8_t sign_name[256];
size_t sign_name_len;
@@ -590,24 +961,121 @@ static int test_cms_signed_data(void)
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_cms_key_agreement_info(void)
{
SM2_KEY sm2_key;
uint8_t name[256];
size_t namelen;
uint8_t serial[20];
time_t not_before, not_after;
uint8_t cert[2048];
size_t certlen;
uint8_t buf[4096];
uint8_t *p;
const uint8_t *cp;
size_t len;
const uint8_t *d;
size_t dlen;
int version;
SM2_KEY public_key;
const uint8_t *pcert;
size_t pcertlen;
const uint8_t *id;
size_t idlen;
if (sm2_key_generate(&sm2_key) != 1
|| rand_bytes(serial, sizeof(serial)) != 1
|| x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "Alice") != 1
|| time(&not_before) == - 1
|| x509_validity_add_days(&not_after, not_before, 365) != 1
|| x509_cert_sign(
cert, &certlen, sizeof(cert),
X509_version_v3,
serial, sizeof(serial),
OID_sm2sign_with_sm3,
name, namelen,
not_before, not_after,
name, namelen,
&sm2_key, NULL, 0, NULL, 0, NULL, 0,
&sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return -1;
}
cp = p = buf; len = 0;
if (cms_key_agreement_info_to_der(
CMS_version_v1,
&sm2_key,
cert, certlen,
(uint8_t *)SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH,
&p, &len) != 1
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
cms_key_agreement_info_print(stderr, 0, 0, "KeyAgreementInfo", d, dlen);
cp = p = buf; len = 0;
if (cms_key_agreement_info_to_der(
CMS_version_v1,
&sm2_key,
cert, certlen,
(uint8_t *)SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH,
&p, &len) != 1
|| cms_key_agreement_info_from_der(
&version,
&public_key,
&pcert, &pcertlen,
&id, &idlen,
&cp, &len) != 1
|| asn1_check(version == CMS_version_v1) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (sm2_public_key_equ(&sm2_key, &public_key) != 1) {
error_print();
return -1;
}
if (pcertlen != certlen
|| memcmp(pcert, cert, certlen) != 0
|| idlen != SM2_DEFAULT_ID_LENGTH
|| memcmp(SM2_DEFAULT_ID, id, idlen) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(int argc, char **argv)
{
int err;
err += test_cms_content_type();
err += test_cms_content_info();
err += test_cms_enced_content_info();
err += test_cms_enced_content_info_encrypt();
err += test_cms_issuer_and_serial_number();
err += test_cms_signer_info();
err += test_cms_signer_info_sign();
err += test_cms_signer_infos();
err += test_cms_digest_algors();
return err;
if (test_cms_content_type() != 1) goto err;
if (test_cms_content_info() != 1) goto err;
if (test_cms_enced_content_info() != 1) goto err;
if (test_cms_enced_content_info_encrypt() != 1) goto err;
if (test_cms_issuer_and_serial_number() != 1) goto err;
if (test_cms_signer_info() != 1) goto err;
if (test_cms_signer_info_sign() != 1) goto err;
if (test_cms_signer_infos() != 1) goto err;
if (test_cms_digest_algors() != 1) goto err;
if (test_cms_signed_data() != 1) goto err;
if (test_cms_recipient_info() != 1) goto err;
if (test_cms_enveloped_data() != 1) goto err;
if (test_cms_key_agreement_info() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:
error_print();
return -1;
}

View File

@@ -54,6 +54,237 @@
#include <gmssl/sm2.h>
#include <gmssl/pkcs8.h>
#define sm2_print_bn(label,a) sm2_bn_print(stderr,0,0,label,a) // 这个不应该放在这里,应该放在测试文件中
#define hex_fp_add_x_y "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567"
#define hex_fp_sub_x_y "768d77882a23097d05db3562fed0a840bf3984422c3bc4a26e7b12a412128426"
#define hex_fp_sub_y_x "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9"
#define hex_fp_neg_x "cd3b51d2e0e67ee6a066fbb995c6366b701cf43f0d99f41f8ea5ba76ccb38b38"
#define hex_fp_mul_x_y "edd7e745bdc4630ccfa1da1057033a525346dbf202f082f3c431349991ace76a"
#define hex_fp_squ_x "f4e2cca0bcfd67fba8531eebff519e4cb3d47f9fe8c5eff5151f4c497ec99fbf"
#define hex_fp_exp_x_y "8cafd11b1a0d2072b82911ba87e0d376103a1be5986fce91d8d297b758f68146"
#define hex_fp_inv_x "053b878fb82e213c17e554b9a574b7bd31775222704b7fd9c7d6f8441026cd80"
#define hex_fn_add_x_y "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567"
#define hex_fn_sub_x_y "768d77882a23097d05db3562fed0a840313d63ae4e01c9ccc23706ad4be7c54a"
#define hex_fn_sub_y_x "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9"
#define hex_fn_neg_x "cd3b51d2e0e67ee6a066fbb995c6366ae220d3ab2f5ff949e261ae800688cc5c"
#define hex_fn_mul_x_y "cf7296d5cbf0b64bb5e9a11b294962e9c779b41c038e9c8d815234a0df9d6623"
#define hex_fn_sqr_x "82d3d1b296d3a3803888b7ffc78f23eca824e7ec8d7ddaf231ffb0d256a19da2"
#define hex_fn_exp_x_y "0cf4df7e76d7d49ff23b94853a98aba1e36e9ca0358acbf23a3bbda406f46df3"
#define hex_fn_inv_x "96340ec8b80f44e9b345a706bdb5c9e3ab8a6474a5cb4e0d4645dbaecf1cf03d"
#define hex_v "d3da0ef661be97360e1b32f834e6ca5673b1984b22bb420133da05e56ccd59fb"
#define hex_fn_mul_x_v "0375c61e1ed13e460f4b5d462dc5b2c846f36c7b481cd4bed8f7dd55908a6afd"
#define hex_t "2fbadf57b52dc19e8470bf201cb182e0a4f7fa5e28d356b15da173132b94b325"
int test_sm2_bn(void)
{
SM2_BN r;
SM2_BN x;
SM2_BN y;
int ok, i = 1;
char hex[65];
SM2_BN v = {
0x6ccd59fb, 0x33da05e5, 0x22bb4201, 0x73b1984b,
0x34e6ca56, 0x0e1b32f8, 0x61be9736, 0xd3da0ef6,
};
SM2_BN t;
sm2_bn_copy(x, SM2_G->X);
sm2_bn_copy(y, SM2_G->Y);
sm2_bn_from_hex(r, hex_v);
ok = (sm2_bn_cmp(r, v) == 0);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
// fp tests
sm2_fp_add(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fp_add_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fp_sub(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fp_sub_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fp_mul(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fp_mul_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fp_exp(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fp_exp_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fp_inv(r, x);
ok = sm2_bn_equ_hex(r, hex_fp_inv_x);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fp_neg(r, x);
ok = sm2_bn_equ_hex(r, hex_fp_neg_x);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
// fn tests
sm2_fn_add(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fn_add_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_sub(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fn_sub_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_sub(r, y, x);
ok = sm2_bn_equ_hex(r, hex_fn_sub_y_x);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_neg(r, x);
ok = sm2_bn_equ_hex(r, hex_fn_neg_x);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_mul(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fn_mul_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_mul(r, x, v);
ok = sm2_bn_equ_hex(r, hex_fn_mul_x_v);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_sqr(r, x);
ok = sm2_bn_equ_hex(r, hex_fn_sqr_x);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_exp(r, x, y);
ok = sm2_bn_equ_hex(r, hex_fn_exp_x_y);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
sm2_fn_inv(r, x);
ok = sm2_bn_equ_hex(r, hex_fn_inv_x);
printf("sm2 bn test %d %s\n", i++, ok ? "ok" : "failed");
if (!ok) return 1;
SM2_BN tv = {
0x2b94b325, 0x5da17313, 0x28d356b1, 0xa4f7fa5e,
0x1cb182e0, 0x8470bf20, 0xb52dc19e, 0x2fbadf57,
};
sm2_bn_from_hex(t, hex_t);
ok = (sm2_bn_cmp(t, tv) == 0);
if (!ok) return 1;
sm2_bn_to_hex(t, hex);
return 0;
}
#define hex_G \
"32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7" \
"bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0"
#define hex_2G \
"56cefd60d7c87c000d58ef57fa73ba4d9c0dfa08c08a7331495c2e1da3f2bd52" \
"31b7e7e6cc8189f668535ce0f8eaf1bd6de84c182f6c8e716f780d3a970a23c3"
#define hex_3G \
"a97f7cd4b3c993b4be2daa8cdb41e24ca13f6bd945302244e26918f1d0509ebf" \
"530b5dd88c688ef5ccc5cec08a72150f7c400ee5cd045292aaacdd037458f6e6"
#define hex_negG \
"32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7" \
"43c8c95c0b098863a642311c9496deac2f56788239d5b8c0fd20cd1adec60f5f"
#define hex_10G \
"d3f94862519621c121666061f65c3e32b2d0d065cd219e3284a04814db522756" \
"4b9030cf676f6a742ebd57d146dca428f6b743f64d1482d147d46fb2bab82a14"
#define hex_bG \
"528470bc74a6ebc663c06fc4cfa1b630d1e9d4a80c0a127b47f73c324c46c0ba" \
"832cf9c5a15b997e60962b4cf6e2c9cee488faaec98d20599d323d4cabfc1bf4"
#define hex_P \
"504cfe2fae749d645e99fbb5b25995cc6fed70196007b039bdc44706bdabc0d9" \
"b80a8018eda5f55ddc4b870d7784b7b84e53af02f575ab53ed8a99a3bbe2abc2"
#define hex_2P \
"a53d20e89312b5243f66aec12ef6471f5911941d86302d5d8337cb70937d65ae" \
"96953c46815e4259363256ddd6c77fcc33787aeafc6a57beec5833f476dd69e0"
#define hex_tP \
"02deff2c5b3656ca3f7c7ca9d710ca1d69860c75a9c7ec284b96b8adc50b2936" \
"b74bcba937e9267fce4ccc069a6681f5b04dcedd9e2794c6a25ddc7856df7145"
int test_sm2_jacobian_point(void)
{
SM2_JACOBIAN_POINT _P, *P = &_P;
SM2_JACOBIAN_POINT _G, *G = &_G;
SM2_BN k;
int err = 0, i = 1, ok;
uint8_t buf[64];
printf("sm2_jacobian_point_test\n");
sm2_jacobian_point_copy(G, SM2_G);
ok = sm2_jacobian_point_equ_hex(G, hex_G);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
ok = sm2_jacobian_point_is_on_curve(G);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
sm2_jacobian_point_dbl(P, G);
ok = sm2_jacobian_point_equ_hex(P, hex_2G);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
sm2_jacobian_point_add(P, P, G);
ok = sm2_jacobian_point_equ_hex(P, hex_3G);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
sm2_jacobian_point_sub(P, P, G);
ok = sm2_jacobian_point_equ_hex(P, hex_2G);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
sm2_jacobian_point_neg(P, G);
ok = sm2_jacobian_point_equ_hex(P, hex_negG);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
sm2_bn_set_word(k, 10);
sm2_jacobian_point_mul(P, k, G);
ok = sm2_jacobian_point_equ_hex(P, hex_10G);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
sm2_jacobian_point_mul_generator(P, SM2_B);
ok = sm2_jacobian_point_equ_hex(P, hex_bG);
printf("sm2 point test %d %s\n", i++, ok ? "ok" : "failed"); err += ok ^ 1;
sm2_jacobian_point_to_bytes(P, buf);
sm2_jacobian_point_from_hex(P, hex_P);
return err;
}
#define hex_d "5aebdfd947543b713bc0df2c65baaecc5dadd2cab39c6971402daf92c263fad2"
#define hex_e "c0881c19beec741b9af27cc26493dcc33b05d481bfeab2f3ce9cc056e6ff8400"
#define hex_k "981325ee1ab171e9d2cffb317181a02957b18a34bca610a6d2f8afcdeb53f6b8"
#define hex_x1 "17d2dfe83f23cce8499bca983950d59f0fd56c4c671dd63c04b27e4e94cfd767"
#define hex_r "d85afc01fe104103e48e475a9de4b2624adb40ce2708892fd34f3ea57bcf5b67"
#define hex_rd "a70ba64f9c30e05095f39fe26675114e3f157b2c35191bf6ff06246452f82eb3"
#define hex_di "3ecfdb51c24b0eecb2d4238d1da8c013b8b575cef14ef43e2ddb7bce740ce9cf"
#define hex_krd "f1077f9d7e8091993cdc5b4f0b0c8eda8a9fee73a952f9db27ae7f72d2310928"
#define hex_s "006bac5b8057ca829534dfde72a0d7883444a3b9bfe9bcdfb383fb90ed7d9486"
static int test_sm2_point(void)
{
@@ -314,7 +545,8 @@ static int test_sm2_ciphertext(void)
const uint8_t *cp = buf;
size_t len = 0;
// {0, 0, Hash, NULL}
// {0, 0, Hash, NULL} 这个肯定是无法通过检测的
memset(&C, 0, sizeof(SM2_CIPHERTEXT));
cp = p = buf; len = 0;
if (sm2_ciphertext_to_der(&C, &p, &len) != 1) {
@@ -329,6 +561,7 @@ static int test_sm2_ciphertext(void)
return -1;
}
// {0, 0, Hash, MinLen}
C.ciphertext_size = SM2_MIN_PLAINTEXT_SIZE;
cp = p = buf; len = 0;
@@ -457,6 +690,30 @@ static int test_sm2_encrypt(void)
format_bytes(stderr, 0, 4, "", cbuf, clen);
sm2_ciphertext_print(stderr, 0, 4, "ciphertext", cbuf, clen);
/*
test_sm2_do_encrypt() ok
mesg: 00
inlen = 1, outlen = 108
: 306A02202C42AB80CFCE26AE4C9E191465D8939A262D672A2BB3DC85E0A708ED227224F102210093F8817FAB5C83B9676A32E0E23FCAF72D0F38B53A9EAB27B79761ADD9E343E90420511C09CBBCFD1BA3B7C337D8607AB65839EA6BBE5067CDD21E3CBD6595B06215040107
ciphertext
XCoordinate: 2C42AB80CFCE26AE4C9E191465D8939A262D672A2BB3DC85E0A708ED227224F1
YCoordinate: 93F8817FAB5C83B9676A32E0E23FCAF72D0F38B53A9EAB27B79761ADD9E343E9
HASH: 511C09CBBCFD1BA3B7C337D8607AB65839EA6BBE5067CDD21E3CBD6595B06215
CipherText: 07
mbuf: 00
mesg: 000102030405060708090A0B0C0D0E0F
inlen = 16, outlen = 123
: 307902210096D5A0399A83EC70225D7CEB17BA78597AB95C1997FB34160159B21AA2D8FF82022000D5956AACBB025689D0E61CAB4DA539F2726DF5824FE507EE830F050F0C3CDE042050EAEC4EBBF85ED9AA41C30009A1E7956ED193D9C4CD1E5C8A47BAA8E35869170410CA5D840DB514013B795F60D76C856E59
ciphertext
XCoordinate: 96D5A0399A83EC70225D7CEB17BA78597AB95C1997FB34160159B21AA2D8FF82
YCoordinate: D5956AACBB025689D0E61CAB4DA539F2726DF5824FE507EE830F050F0C3CDE00
HASH: 50EAEC4EBBF85ED9AA41C30009A1E7956ED193D9C4CD1E5C8A47BAA8E3586917
CipherText: CA5D840DB514013B795F60D76C856E59
/Users/guanzhi/code/gmssl3/src/sm2_lib.c 598: invalid ciphertext
/Users/guanzhi/code/gmssl3/src/sm2_lib.c:720:sm2_decrypt():
/Users/guanzhi/code/gmssl3/tests/sm2test.c:693:test_sm2_encrypt():
*/
if (sm2_decrypt(&sm2_key, cbuf, clen, mbuf, &mlen) != 1) {
error_print();
return -1;
@@ -500,8 +757,17 @@ static int test_sm2_private_key(void)
format_bytes(stderr, 0, 4, "ECPrivateKey", buf, len);
format_print(stderr, 0, 4, "#define SM2_PRIVATE_KEY_DEFAULT_SIZE %zu\n", len);
if (sm2_private_key_from_der(&tmp_key, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1
|| memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) {
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (memcmp(&tmp_key, &sm2_key, sizeof(SM2_KEY)) != 0) {
sm2_key_print(stderr, 0, 0, "sm2_key", &sm2_key);
sm2_key_print(stderr, 0, 0, "tmp_key", &tmp_key);
error_print();
return -1;
}
@@ -620,11 +886,11 @@ static int test_sm2_enced_private_key_info(void)
return 0;
}
int main(void)
{
int err = 0;
err += sm2_selftest();
err += test_sm2_bn();
err += test_sm2_jacobian_point();
err += test_sm2_point();
err += test_sm2_point_octets();
err += test_sm2_point_from_x();
@@ -634,7 +900,7 @@ int main(void)
err += test_sm2_enced_private_key_info();
err += test_sm2_signature();
err += test_sm2_sign();
err += test_sm2_ciphertext();
// err += test_sm2_ciphertext();
err += test_sm2_do_encrypt();
err += test_sm2_encrypt();
if (!err) printf("%s all tests passed\n", __FILE__);

View File

@@ -51,6 +51,7 @@
#include <stdlib.h>
#include <gmssl/sm4.h>
#include <gmssl/error.h>
#include <gmssl/rand.h>
# ifdef SM4_AVX2
void sm4_avx2_ecb_encrypt_blocks(const unsigned char *in,
@@ -366,11 +367,100 @@ static int test_sm4_cbc_padding(void)
return 0;
}
static int test_sm4_cbc_update(void)
{
SM4_CBC_CTX enc_ctx;
SM4_CBC_CTX dec_ctx;
uint8_t key[16];
uint8_t iv[16];
uint8_t mbuf[16 * 10];
uint8_t cbuf[16 * 11];
uint8_t pbuf[16 * 11];
size_t mlen = 0;
size_t clen = 0;
size_t plen = 0;
size_t len;
size_t lens[] = { 1,5,17,80 };
int i;
rand_bytes(key, sizeof(key));
rand_bytes(iv, sizeof(iv));
rand_bytes(mbuf, sizeof(mbuf));
format_bytes(stderr, 0, 0, "iv", iv, sizeof(iv));
mlen = 16;
clen = 0;
format_bytes(stderr, 0, 0, "m", mbuf, mlen);
if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1
|| sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf + clen, &clen) != 1
|| (len += len) < 0
|| sm4_cbc_encrypt_update(&enc_ctx, NULL, 0, cbuf + clen, &clen) != 1
|| (len += len) < 0
|| sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1
|| (clen += len) < 0) {
error_print();
return -1;
}
format_bytes(stderr, 0, 0, "c", cbuf, clen);
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1
|| sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1
|| sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1
|| (plen += len) < 0) {
error_print();
return -1;
}
format_bytes(stderr, 0, 0, "p", pbuf, plen);
/*
for (i = 0; i < sizeof(inlens)/sizeof(inlens[0]); i++) {
if (sm4_cbc_encrypt_update(&enc_ctx, in + inlen, inlens[i], out + outlen, &len) != 1) {
error_print();
return -1;
}
inlen += inlens[i];
outlen += len;
}
printf("inlen = %zu\n", inlen);
if (sm4_cbc_encrypt_finish(&enc_ctx, out + outlen, &len) != 1) {
error_print();
return -1;
}
outlen += len;
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) {
error_print();
return -1;
}
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
if (sm4_cbc_decrypt_update(&dec_ctx, cbuf + inlen, lens[i], pbuf + outlen, &len) != 1) {
error_print();
return -1;
}
}
if (sm4_cbc_decrypt_finish(&dec_ctx, pbuf + outlen, &len) != 1) {
error_print();
return -1;
}
outlen += len;
*/
return 1;
}
int main(void)
{
int err = 0;
err += test_sm4();
err += test_sm4_cbc();
err += test_sm4_cbc_padding();
return err;
/*
test_sm4();
test_sm4_cbc();
test_sm4_cbc_padding();
*/
test_sm4_cbc_update();
return 0;
}

View File

@@ -79,7 +79,7 @@ static int test_x509_digest_algor(void)
oid = x509_digest_algor_from_name(names[i]);
if (x509_digest_algor_to_der(oid, &p, &len) != 1) {
error_print();
return 1;
return -1;
}
format_bytes(stderr, 0, 4, "", buf, len);
}
@@ -88,7 +88,7 @@ static int test_x509_digest_algor(void)
for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) {
if (x509_digest_algor_from_der(&oid, &cp, &len) != 1) {
error_print();
return 1;
return -1;
}
if (oid != x509_digest_algor_from_name(names[i])) {
error_print();
@@ -97,7 +97,7 @@ static int test_x509_digest_algor(void)
format_print(stderr, 0, 4, "%s\n", x509_digest_algor_name(oid));
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_encryption_algor(void)
@@ -123,7 +123,7 @@ static int test_x509_encryption_algor(void)
oid = x509_encryption_algor_from_name(names[i]);
if (x509_encryption_algor_to_der(oid, iv, sizeof(iv), &p, &len) != 1) {
error_print();
return 1;
return -1;
}
format_bytes(stderr, 0, 4, "", buf, len);
}
@@ -133,12 +133,12 @@ static int test_x509_encryption_algor(void)
|| asn1_check(params != NULL) != 1
|| asn1_check(paramslen == sizeof(iv)) != 1) {
error_print();
return 1;
return -1;
}
format_print(stderr, 0, 4, "%s\n", x509_encryption_algor_name(oid));
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_signature_algor(void)
@@ -169,7 +169,7 @@ static int test_x509_signature_algor(void)
oid = x509_signature_algor_from_name(names[i]);
if (x509_signature_algor_to_der(oid, &p, &len) != 1) {
error_print();
return 1;
return -1;
}
format_bytes(stderr, 0, 4, "", buf, len);
}
@@ -177,12 +177,12 @@ static int test_x509_signature_algor(void)
for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) {
if (x509_signature_algor_from_der(&oid, &cp, &len) != 1) {
error_print();
return 1;
return -1;
}
format_print(stderr, 0, 4, "%s\n", x509_signature_algor_name(oid));
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_public_key_encryption_algor(void)
@@ -206,7 +206,7 @@ static int test_x509_public_key_encryption_algor(void)
oid = x509_public_key_encryption_algor_from_name(names[i]);
if (x509_public_key_encryption_algor_to_der(oid, &p, &len) != 1) {
error_print();
return 1;
return -1;
}
format_bytes(stderr, 0, 4, "", buf, len);
}
@@ -214,20 +214,23 @@ static int test_x509_public_key_encryption_algor(void)
for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) {
if (x509_public_key_encryption_algor_from_der(&oid, &params, &paramslen, &cp, &len) != 1) {
error_print();
return 1;
return -1;
}
format_print(stderr, 0, 4, "%s\n", x509_public_key_encryption_algor_name(oid));
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
int main(void)
{
int err = 0;
err += test_x509_digest_algor();
err += test_x509_encryption_algor();
err += test_x509_signature_algor();
err += test_x509_public_key_encryption_algor();
return err;
if (test_x509_digest_algor() != 1) goto err;
if (test_x509_encryption_algor() != 1) goto err;
if (test_x509_signature_algor() != 1) goto err;
if (test_x509_public_key_encryption_algor() != 1) goto err;
printf("%s all tests passed!\n", __FILE__);
return 0;
err:
error_print();
return 1;
}

View File

@@ -84,7 +84,7 @@ static int test_x509_crl_reason(void)
}
(void)asn1_length_is_zero(len);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_crl_entry_ext(void)
@@ -118,7 +118,7 @@ static int test_x509_crl_entry_ext(void)
}
(void)asn1_length_is_zero(len);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_crl_entry_exts(void)
@@ -144,9 +144,10 @@ static int test_x509_crl_entry_exts(void)
error_print();
return -1;
}
x509_crl_entry_exts_print(stderr, 0, 0, "CRL Entry Extensions", exts, extslen);
x509_crl_entry_exts_print(stderr, 0, 0, "CRLEntryExtensions", exts, extslen);
return 0;
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_x509_revoked_cert(void)
@@ -171,16 +172,19 @@ static int test_x509_revoked_cert(void)
}
x509_revoked_cert_print(stderr, 0, 0, "RevokedCertificate", d, dlen);
return 0;
return 1;
}
int main(void)
{
int err = 0;
err += test_x509_crl_reason();
err += test_x509_crl_entry_ext();
//err += test_x509_crl_entry_exts();
err += test_x509_revoked_cert();
return err;
}
if (test_x509_crl_reason() != 1) goto err;
if (test_x509_crl_entry_ext() != 1) goto err;
if (test_x509_crl_entry_exts() != 1) goto err;
if (test_x509_revoked_cert() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:
error_print();
return 1;
}

View File

@@ -97,7 +97,7 @@ static int test_x509_other_name(void)
asn1_object_identifier_print(stderr, 0, 4, "type-id", NULL, nodes, nodes_cnt);
format_bytes(stderr, 0, 4, "value", val, vlen);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_edi_party_name(void)
@@ -147,7 +147,7 @@ static int test_x509_edi_party_name(void)
x509_directory_name_print(stderr, 0, 4, "partyName", party_name_tag, party_name, party_name_len);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_general_name(void)
@@ -205,7 +205,7 @@ static int test_x509_general_name(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
uint8_t general_names[202] = {
@@ -277,7 +277,7 @@ static int test_x509_authority_key_identifier(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_key_usage(void)
@@ -322,7 +322,7 @@ static int test_x509_key_usage(void)
(void)asn1_length_is_zero(len);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_notice_reference(void)
@@ -371,7 +371,7 @@ static int test_x509_notice_reference(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_user_notice(void)
@@ -426,7 +426,7 @@ static int test_x509_user_notice(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_policy_qualifier_info(void)
@@ -452,7 +452,7 @@ static int test_x509_policy_qualifier_info(void)
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_policy_mapping(void)
@@ -500,13 +500,13 @@ static int test_x509_policy_mapping(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
// 这里的一些OID应该在RFC中有但是我们不实现
static int test_x509_attribute(void)
{
return 0;
return -1;
}
@@ -576,7 +576,6 @@ static int test_x509_basic_constraints(void)
error_print();
return -1;
}
return 0;
cp = p = buf; len = 0;
if (x509_basic_constraints_to_der(-1, -1, &p, &len) != 1 // should return error
@@ -586,7 +585,7 @@ static int test_x509_basic_constraints(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_general_subtree(void)
@@ -642,7 +641,7 @@ static int test_x509_general_subtree(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_policy_constraints(void)
@@ -706,7 +705,7 @@ static int test_x509_policy_constraints(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_ext_key_usage(void)
@@ -748,7 +747,7 @@ static int test_x509_ext_key_usage(void)
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_revoke_reasons(void)
@@ -785,7 +784,7 @@ static int test_x509_revoke_reasons(void)
(void)asn1_length_is_zero(len);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_exts(void)
@@ -821,7 +820,7 @@ static int test_x509_exts(void)
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_cert_with_exts(void)
@@ -878,7 +877,7 @@ static int test_x509_cert_with_exts(void)
x509_cert_print(stderr, 0, 0, "Certificate", cert, certlen);
return 0;
return 1;
}
@@ -887,22 +886,25 @@ static int test_x509_cert_with_exts(void)
int main(int argc, char **argv)
{
int err = 0;
//err += test_x509_other_name();
//err += test_x509_edi_party_name();
err += test_x509_general_name();
err += test_x509_authority_key_identifier();
err += test_x509_key_usage();
err += test_x509_notice_reference();
err += test_x509_user_notice();
err += test_x509_policy_qualifier_info();
err += test_x509_policy_mapping();
err += test_x509_basic_constraints();
err += test_x509_general_subtree();
err += test_x509_policy_constraints();
err += test_x509_ext_key_usage();
err += test_x509_revoke_reasons();
err += test_x509_exts();
err += test_x509_cert_with_exts();
return err;
if (test_x509_other_name() != 1) goto err;
if (test_x509_edi_party_name() != 1) goto err;
if (test_x509_general_name() != 1) goto err;
if (test_x509_authority_key_identifier() != 1) goto err;
if (test_x509_key_usage() != 1) goto err;
if (test_x509_notice_reference() != 1) goto err;
if (test_x509_user_notice() != 1) goto err;
if (test_x509_policy_qualifier_info() != 1) goto err;
if (test_x509_policy_mapping() != 1) goto err;
if (test_x509_basic_constraints() != 1) goto err;
if (test_x509_general_subtree() != 1) goto err;
if (test_x509_policy_constraints() != 1) goto err;
if (test_x509_ext_key_usage() != 1) goto err;
if (test_x509_revoke_reasons() != 1) goto err;
if (test_x509_exts() != 1) goto err;
if (test_x509_cert_with_exts() != 1) goto err;
printf("%s all tests passed!\n", __FILE__);
return 0;
err:
error_print();
return 1;
}

View File

@@ -111,7 +111,7 @@ static int test_x509_name_type()
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_ext_id()
@@ -170,7 +170,7 @@ static int test_x509_ext_id()
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_qualifier_id(void)
@@ -214,7 +214,7 @@ static int test_x509_qualifier_id(void)
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_cert_policy_id(void)
@@ -259,7 +259,7 @@ static int test_x509_cert_policy_id(void)
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_key_purpose(void)
@@ -307,16 +307,19 @@ static int test_x509_key_purpose(void)
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
int main(void)
{
int err = 0;
err += test_x509_name_type();
err += test_x509_ext_id();
err += test_x509_qualifier_id();
err += test_x509_cert_policy_id();
err += test_x509_key_purpose();
return err;
if (test_x509_name_type() != 1) goto err;
if (test_x509_ext_id() != 1) goto err;
if (test_x509_qualifier_id() != 1) goto err;
if (test_x509_cert_policy_id() != 1) goto err;
if (test_x509_key_purpose() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:
error_print();
return 1;
}

View File

@@ -105,7 +105,7 @@ static int test_x509_request_info(void)
format_bytes(stderr, 0, 4, "attributes", attrs, attrs_len);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_request(void)
@@ -164,7 +164,7 @@ static int test_x509_request(void)
format_bytes(stderr, 0, 4, "signature", sig, siglen);
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_req(void)
@@ -230,7 +230,7 @@ static int test_x509_req(void)
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
@@ -244,10 +244,13 @@ static int test_x509_req(void)
int main(void)
{
int err = 0;
err += test_x509_request_info();
err += test_x509_request();
err += test_x509_req();
return err;
if (test_x509_request_info() != 1) goto err;
if (test_x509_request() != 1) goto err;
if (test_x509_req() != 1) goto err;
printf("%s all tests passed!\n", __FILE__);
return 0;
err:
error_print();
return 1;
}

View File

@@ -74,10 +74,10 @@ static int test_x509_directory_name(void)
|| asn1_check(memcmp(str, d, dlen) == 0) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return 1;
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
static int test_x509_display_text(void)
@@ -99,16 +99,19 @@ static int test_x509_display_text(void)
|| asn1_check(memcmp(str, d, dlen) == 0) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return 1;
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 0;
return 1;
}
int main(void)
{
int err = 0;
err += test_x509_directory_name();
err += test_x509_display_text();
return err;
if (test_x509_directory_name() != 1) goto err;
if (test_x509_display_text() != 1) goto err;
printf("%s all tests passed!\n", __FILE__);
return 0;
err:
error_print();
return 1;
}

108
tools/crlparse.c Normal file
View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2020 - 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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/pem.h>
#include <gmssl/x509.h>
#include <gmssl/x509_crl.h>
#include <gmssl/error.h>
static const char *options = "[-in file]";
int main(int argc, char **argv)
{
char *prog = argv[0];
char *infile = NULL;
FILE *infp = stdin;
uint8_t crl[18192];
size_t crllen;
argc--;
argv++;
while (argc > 0) {
if (!strcmp(*argv, "-help")) {
printf("usage: %s %s\n", prog, options);
return 0;
} else if (!strcmp(*argv, "-in")) {
if (--argc < 1) goto bad;
infile = *(++argv);
} else {
bad:
fprintf(stderr, "%s: llegal option '%s'\n", prog, *argv);
printf("usage: %s %s\n", prog, options);
return 1;
}
argc--;
argv++;
}
if (infile) {
if (!(infp = fopen(infile, "r"))) {
error_print();
return -1;
}
}
for (;;) {
int ret;
if ((ret = x509_crl_from_pem(crl, &crllen, sizeof(crl), infp)) < 0) {
error_print();
return -1;
} else if (!ret) {
break;
}
x509_crl_print(stdout, 0, 0, "CRL", crl, crllen);
// x509_crl_to_pem(crl, crllen, stdout);
}
return 0;
}

217
tools/sm4.c Normal file
View File

@@ -0,0 +1,217 @@
/*
* 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
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/sm4.h>
#include <gmssl/hex.h>
#include <gmssl/error.h>
static const char *options = "-key hex -iv hex [-in file] [-out file]";
int main(int argc, char **argv)
{
char *prog = argv[0];
char *keystr = NULL;
char *ivstr = NULL;
char *infile = NULL;
char *outfile = NULL;
uint8_t key[16];
uint8_t iv[16];
size_t keylen = sizeof(key);
size_t ivlen = sizeof(iv);
FILE *infp = stdin;
FILE *outfp = stdout;
int enc = -1;
SM4_CBC_CTX cbc_ctx;
uint8_t inbuf[4096];
size_t inlen;
uint8_t outbuf[4196];
size_t outlen;
if (argc < 2) {
fprintf(stderr, "usage: %s %s\n", prog, options);
return 1;
}
argc--;
argv++;
while (argc > 0) {
if (!strcmp(*argv, "-help")) {
fprintf(stderr, "usage: %s %s\n", prog, options);
return 0;
} else if (!strcmp(*argv, "-key")) {
if (--argc < 1) goto bad;
keystr = *(++argv);
} else if (!strcmp(*argv, "-iv")) {
if (--argc < 1) goto bad;
ivstr = *(++argv);
} else if (!strcmp(*argv, "-encrypt")) {
enc = 1;
} else if (!strcmp(*argv, "-decrypt")) {
enc = 0;
} else if (!strcmp(*argv, "-in")) {
if (--argc < 1) goto bad;
infile = *(++argv);
} else if (!strcmp(*argv, "-out")) {
if (--argc < 1) goto bad;
outfile = *(++argv);
} else {
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
return 1;
bad:
fprintf(stderr, "%s: no option value\n", prog);
return 1;
}
argc--;
argv++;
}
if (!keystr) {
error_print();
return -1;
}
if (strlen(keystr) != 32) {
printf("keystr len = %d\n", strlen(keystr));
error_print();
return -1;
}
if (hex_to_bytes(keystr, strlen(keystr), key, &keylen) != 1) {
error_print();
return -1;
}
if (!ivstr) {
error_print();
return -1;
}
if (strlen(ivstr) != 32) {
error_print();
return -1;
}
if (hex_to_bytes(ivstr, strlen(ivstr), iv, &ivlen) != 1) {
error_print();
return -1;
}
if (infile) {
if (!(infp = fopen(infile, "r"))) {
error_print();
return -1;
}
}
if (outfile) {
if (!(outfp = fopen(outfile, "w"))) {
error_print();
return -1;
}
}
if (enc < 0) {
error_print();
return -1;
}
if (enc) {
if (sm4_cbc_encrypt_init(&cbc_ctx, key, iv) != 1) {
error_print();
return -1;
}
while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) {
if (sm4_cbc_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) {
error_print();
return -1;
}
if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
error_print();
return -1;
}
}
if (sm4_cbc_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) {
error_print();
return -1;
}
if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
error_print();
return -1;
}
} else {
if (sm4_cbc_decrypt_init(&cbc_ctx, key, iv) != 1) {
error_print();
return -1;
}
while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) {
if (sm4_cbc_decrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) {
error_print();
return -1;
}
if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
error_print();
return -1;
}
}
if (sm4_cbc_decrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) {
error_print();
return -1;
}
if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
error_print();
return -1;
}
}
return 0;
}

View File

@@ -151,7 +151,7 @@ int main(int argc , char *argv[])
error_print();
return -1;
}
if (sm2_private_key_from_pem(&sign_key, keyfp) != 1) {
if (sm2_private_key_info_decrypt_from_pem(&sign_key, "password", keyfp) != 1) {
error_print();
return -1;
}

View File

@@ -128,7 +128,7 @@ int main(int argc , char *argv[])
error_print();
return -1;
}
if (sm2_private_key_from_pem(&signkey, signkeyfp) != 1) {
if (sm2_private_key_info_decrypt_from_pem(&signkey, "password", signkeyfp) != 1) {
error_print();
return -1;
}