mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-30 09:43:38 +08:00
update
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
75
include/gmssl/engine.h
Normal 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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user