mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
1115 lines
39 KiB
C
1115 lines
39 KiB
C
/*
|
||
* 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_X509_H
|
||
#define GMSSL_X509_H
|
||
|
||
|
||
#include <time.h>
|
||
#include <string.h>
|
||
#include <stdint.h>
|
||
#include <stdlib.h>
|
||
#include <gmssl/sm2.h>
|
||
#include <gmssl/oid.h>
|
||
#include <gmssl/asn1.h>
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
|
||
/*
|
||
ASN.1 API 规则
|
||
|
||
* SEQUENCE OF/SET OF 类型是存储类型
|
||
* 如果一个CHOICE类型可选项中有存储类型,那么这个CHOICE也设置为存储类型
|
||
|
||
*/
|
||
|
||
|
||
enum X509_Version {
|
||
X509_version_v1 = 0,
|
||
X509_version_v2 = 1,
|
||
X509_version_v3 = 2,
|
||
};
|
||
|
||
int x509_time_to_der(time_t a, uint8_t **out, size_t *outlen);
|
||
int x509_time_from_der(time_t *a, const uint8_t **in, size_t *inlen);
|
||
|
||
typedef struct {
|
||
time_t not_before;
|
||
time_t not_after;
|
||
} X509_VALIDITY;
|
||
|
||
int x509_validity_set_days(X509_VALIDITY *a, time_t not_before, int days);
|
||
int x509_validity_to_der(const X509_VALIDITY *a, uint8_t **out, size_t *outlen);
|
||
int x509_validity_from_der(X509_VALIDITY *a, const uint8_t **in, size_t *inlen);
|
||
int x509_validity_print(FILE *fp, const X509_VALIDITY *validity, int format, int indent);
|
||
|
||
/*
|
||
DirectoryString ::= CHOICE {
|
||
teletexString TeletexString (SIZE (1..MAX)),
|
||
printableString PrintableString (SIZE (1..MAX)),
|
||
universalString UniversalString (SIZE (1..MAX)),
|
||
utf8String UTF8String (SIZE (1..MAX)),
|
||
bmpString BMPString (SIZE (1..MAX)),
|
||
}
|
||
DirectoryString 实际上就是一个 Universal 类型,因此提供和 asn1.h 中基本类型一致的接口
|
||
*/
|
||
int x509_directory_string_to_der(int tag, const char *a, size_t alen, uint8_t **out, size_t *outlen);
|
||
int x509_directory_string_from_der(int *tag, const char **a, size_t *alen, const uint8_t **in, size_t *inlen);
|
||
|
||
|
||
/*
|
||
Name ::= SEQUENCE OF RelativeDistinguishedName
|
||
|
||
RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
|
||
-- 我们只支持 SIZE == 1 的情况
|
||
|
||
AttributeTypeAndValue ::= SEQUENCE {
|
||
type OBJECT IDENTIFIER,
|
||
value ANY -- DEFINED BY AttributeType
|
||
-- mostly DirectoryString or PrintableString
|
||
}
|
||
|
||
type == domainComponent 可能出现多次,因此目前X509_NAME并不支持这种情况
|
||
这个在实际中出现的多吗?
|
||
|
||
*/
|
||
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[256];
|
||
} X509_RDN;
|
||
|
||
int x509_rdn_to_der(int oid, int tag, const char *str, uint8_t **out, size_t *outlen);
|
||
int x509_rdn_from_der(int *oid, int *tag, const char **str, size_t *slen, const uint8_t **in, size_t *inlen);
|
||
|
||
typedef struct {
|
||
int count;
|
||
int oids[8];
|
||
int tags[8];
|
||
|
||
char country[3]; // printableString
|
||
char state_or_province[129];
|
||
char locality[129];
|
||
char org[65];
|
||
char org_unit[65];
|
||
char common_name[65];
|
||
char serial_number[65]; // printableString
|
||
char dn_qualifier[65]; // printableString
|
||
} X509_NAME;
|
||
|
||
int x509_name_add_rdn_ex(X509_NAME *a, int oid, int tag, const char *str, size_t len);
|
||
int x509_name_equ(const X509_NAME *a, const X509_NAME *b);
|
||
int x509_name_from_der(X509_NAME *a, const uint8_t **in, size_t *inlen);
|
||
int x509_name_to_der(const X509_NAME *a, uint8_t **out, size_t *outlen);
|
||
int x509_name_print(FILE *fp, const X509_NAME *a, int format, int indent);
|
||
|
||
|
||
#define x509_name_add_rdn(a,oid,tag,s) x509_name_add_rdn_ex((a),(oid),(tag),(s),strlen(s))
|
||
#define x509_name_set_country(a,s) x509_name_add_rdn((a),OID_at_countryName,ASN1_TAG_PrintableString,(s))
|
||
#define x509_name_set_state_or_province(a,s) x509_name_add_rdn((a),OID_at_stateOrProvinceName,ASN1_TAG_PrintableString,(s))
|
||
#define x509_name_set_organization(a,s) x509_name_add_rdn((a),OID_at_organizationName,ASN1_TAG_PrintableString,(s))
|
||
#define x509_name_set_organizational_unit(a,s) x509_name_add_rdn((a),OID_at_organizationalUnitName,ASN1_TAG_PrintableString,(s))
|
||
#define x509_name_set_common_name(a,s) x509_name_add_rdn((a),OID_at_commonName,ASN1_TAG_PrintableString,(s))
|
||
|
||
/*
|
||
AlgorithmIdentifier ::= SEQUENCE {
|
||
algorithm OBJECT IDENTIFIER,
|
||
parameters ANY DEFINED BY algorithm OPTIONAL }
|
||
|
||
SignatureAlgorithm 是特殊的 AlgorithmIdentifier
|
||
当 algorithm 为 ECDSA/SM2 时,parameters 为空
|
||
当 algorithm 为 RSA 时,parameters 为 ASN1_NULL 对象
|
||
*/
|
||
int x509_signature_algor_to_der(int oid, uint8_t **out, size_t *outlen);
|
||
int x509_signature_algor_from_der(int *oid, const uint8_t **in, size_t *inlen);
|
||
|
||
const char *x509_digest_algor_name(int oid);
|
||
|
||
int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen);
|
||
int x509_digest_algor_from_der(int *oid, uint32_t *nodes, size_t *nodes_count,
|
||
const uint8_t **in, size_t *inlen);
|
||
int x509_encryption_algor_to_der(int cipher, const uint8_t *iv, size_t ivlen,
|
||
uint8_t **out, size_t *outlen);
|
||
int x509_encryption_algor_from_der(int *cipher,
|
||
const uint8_t **iv, size_t *ivlen,
|
||
const uint8_t **in, size_t *inlen);
|
||
int x509_public_key_encryption_algor_to_der(int algor, uint8_t **out, size_t *outlen);
|
||
int x509_public_key_encryption_algor_from_der(int *algor,
|
||
uint32_t *nodes, size_t *nodes_count,
|
||
const uint8_t *params, size_t *params_len,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
|
||
/*
|
||
SubjectPublicKeyInfo ::= SEQUENCE {
|
||
algorithm AlgorithmIdentifier,
|
||
subjectPublicKey BIT STRING }
|
||
|
||
algorithm.algorithm = OID_x9_62_ecPublicKey;
|
||
algorithm.parameters = OID_sm2p256v1;
|
||
subjectPublicKey = ECPoint
|
||
*/
|
||
typedef struct {
|
||
int algor_oid;
|
||
int curve_oid;
|
||
SM2_KEY sm2_key;
|
||
} X509_PUBLIC_KEY_INFO;
|
||
|
||
int x509_public_key_info_set_sm2(X509_PUBLIC_KEY_INFO *a, const SM2_KEY *sm2_key);
|
||
#define x509_public_key_info_set(a,pk) x509_public_key_info_set_sm2((a),(pk))
|
||
int x509_public_key_info_to_der(const X509_PUBLIC_KEY_INFO *a, uint8_t **out, size_t *outlen);
|
||
int x509_public_key_info_from_der(X509_PUBLIC_KEY_INFO *a, const uint8_t **in, size_t *inlen);
|
||
int x509_public_key_info_print(FILE *fp, const X509_PUBLIC_KEY_INFO *a, int format, int indent);
|
||
|
||
/*
|
||
Extension ::= SEQUENCE {
|
||
extnID OBJECT IDENTIFIER,
|
||
critical BOOLEAN DEFAULT FALSE,
|
||
extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value
|
||
*/
|
||
const char *x509_extension_oid_name(int oid);
|
||
int x509_extension_oid_to_der(int oid, uint8_t **out, size_t *outlen);
|
||
int x509_extension_oid_from_der(int *oid, uint32_t *nodes, size_t *nodes_count, const uint8_t **in, size_t *inlen);
|
||
|
||
int x509_extension_to_der(int oid,
|
||
int is_critical, const uint8_t *data, size_t datalen,
|
||
uint8_t **out, size_t *outlen);
|
||
int x509_extension_from_der(int *oid, uint32_t *nodes, size_t *nodes_count,
|
||
int *is_critical, const uint8_t **data, size_t *datalen,
|
||
const uint8_t **in, size_t *inlen);
|
||
int x509_extension_print(FILE *fp, int oid, const uint32_t *nodes, size_t nodes_count,
|
||
int is_critical, const uint8_t *data, size_t datalen,
|
||
int format, int indent);
|
||
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[2048];
|
||
} X509_EXTENSIONS;
|
||
|
||
int x509_extensions_add_item(X509_EXTENSIONS *a,
|
||
int oid, int is_critical, const uint8_t *data, size_t datalen);
|
||
int x509_extensions_get_next_item(const X509_EXTENSIONS *a, const uint8_t **next,
|
||
int *oid, uint32_t *nodes, size_t *nodes_count,
|
||
int *is_critical, const uint8_t **data, size_t *datalen);
|
||
int x509_extensions_print(FILE *fp, const X509_EXTENSIONS *a, int format, int indent);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
typedef struct {
|
||
int version; // [0] EXPLICIT INTEGER DEFAULT v1
|
||
uint8_t serial_number[20]; // INTEGER
|
||
size_t serial_number_len;
|
||
int signature_algor; // AlgorithmIdentifier
|
||
X509_NAME issuer;
|
||
X509_VALIDITY validity;
|
||
X509_NAME subject;
|
||
X509_PUBLIC_KEY_INFO subject_public_key_info;
|
||
uint8_t issuer_unique_id[64]; // [1] IMPLICIT BIT STRING OPTIONAL
|
||
size_t issuer_unique_id_len;
|
||
uint8_t subject_unique_id[64]; // [2] IMPLICIT BIT STRING OPTIONAL
|
||
size_t subject_unique_id_len;
|
||
X509_EXTENSIONS extensions; // [3] EXPLICIT, If present, version MUST be v3
|
||
} X509_TBS_CERTIFICATE;
|
||
|
||
int x509_tbs_certificate_to_der(const X509_TBS_CERTIFICATE *a, uint8_t **out, size_t *outlen);
|
||
int x509_tbs_certificate_from_der(X509_TBS_CERTIFICATE *a, const uint8_t **in, size_t *inlen);
|
||
|
||
|
||
|
||
/*
|
||
Certificate ::= SEQUENCE {
|
||
tbsCertificate TBSCertificate,
|
||
signatureAlgorithm AlgorithmIdentifier,
|
||
signatureValue BIT STRING }
|
||
*/
|
||
typedef struct {
|
||
X509_TBS_CERTIFICATE tbs_certificate;
|
||
int signature_algor;
|
||
uint8_t signature[256];
|
||
size_t signature_len;
|
||
} X509_CERTIFICATE;
|
||
|
||
|
||
int x509_certificate_set_version(X509_CERTIFICATE *cert, int version);
|
||
int x509_certificate_set_serial_number(X509_CERTIFICATE *cert, const uint8_t *sn, size_t snlen);
|
||
int x509_certificate_set_signature_algor(X509_CERTIFICATE *cert, int oid); // 这个应该直接指定SM2吗?
|
||
int x509_certificate_set_issuer(X509_CERTIFICATE *cert, const X509_NAME *name);
|
||
int x509_certificate_set_subject(X509_CERTIFICATE *cert, const X509_NAME *name);
|
||
int x509_certificate_set_validity(X509_CERTIFICATE *cert, time_t not_before, int days);
|
||
int x509_certificate_set_subject_public_key_info_sm2(X509_CERTIFICATE *cert, const SM2_KEY *sm2_key);
|
||
int x509_certificate_set_issuer_unique_id(X509_CERTIFICATE *cert, const uint8_t *id, size_t idlen);
|
||
int x509_certificate_set_subject_unique_id(X509_CERTIFICATE *cert, const uint8_t *id, size_t idlen);
|
||
int x509_certificate_set_issuer_unique_id_from_public_key_sm2(X509_CERTIFICATE *cert, const SM2_KEY *sm2_key);
|
||
int x509_certificate_set_subject_unique_id_from_public_key_sm2(X509_CERTIFICATE *cert, const SM2_KEY *sm2_key);
|
||
#define x509_certificate_set_subject_public_key_info(c,pk) x509_certificate_set_subject_public_key_info_sm2((c),(pk))
|
||
#define x509_certificate_set_issuer_unique_id_from_public_key(c,pk) x509_certificate_set_issuer_unique_id_from_public_key_sm2((c),(pk))
|
||
#define x509_certificate_set_subject_unique_id_from_public_key(c,pk) x509_certificate_set_subject_unique_id_from_public_key_sm2((c),(pk))
|
||
|
||
|
||
int x509_certificate_add_extension(X509_CERTIFICATE *a, int oid, int is_critical,
|
||
const uint8_t *data, size_t datalen);
|
||
int x509_certificate_get_extension_from_oid(const X509_CERTIFICATE *a, int oid,
|
||
int *is_critical, const uint8_t **data, size_t *datalen);
|
||
|
||
int x509_certificate_sign_sm2(X509_CERTIFICATE *cert, const SM2_KEY *key);
|
||
int x509_certificate_verify_sm2(const X509_CERTIFICATE *cert, const SM2_KEY *sm2_key);
|
||
int x509_certificate_get_public_key_sm2(const X509_CERTIFICATE *cert, SM2_KEY *sm2_key);
|
||
#define x509_certificate_sign(c,sk) x509_certificate_sign_sm2((c),(sk))
|
||
#define x509_certificate_verify(c,pk) x509_certificate_verify_sm2((c),(pk))
|
||
#define x509_certificate_get_public_key(c,pk) x509_certificate_get_public_key_sm2((c),(pk))
|
||
|
||
int x509_certificate_to_der(const X509_CERTIFICATE *a, uint8_t **out, size_t *outlen);
|
||
int x509_certificate_to_pem(const X509_CERTIFICATE *a, FILE *fp);
|
||
int x509_certificate_from_der(X509_CERTIFICATE *a, const uint8_t **in, size_t *inlen);
|
||
int x509_certificate_from_pem(X509_CERTIFICATE *a, FILE *fp);
|
||
int x509_certificate_print(FILE *fp, const X509_CERTIFICATE *a, int format, int indent);
|
||
|
||
int x509_certificate_from_pem_by_name(X509_CERTIFICATE *cert, FILE *certs_fp, const X509_NAME *issuer);
|
||
|
||
int x509_certificate_verify_by_certificate(const X509_CERTIFICATE *cert, const X509_CERTIFICATE *cacert);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// Extension 1 AuthorityKeyIdentifier
|
||
|
||
/*
|
||
OtherName ::= SEQUENCE {
|
||
type-id OBJECT IDENTIFIER,
|
||
value [0] EXPLICIT ANY DEFINED BY type-id }
|
||
*/
|
||
int x509_other_name_to_der_ex(int tag,
|
||
int oid, const uint32_t *nodes, size_t nodes_count,
|
||
const uint8_t *value, size_t valuelen,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_other_name_from_der_ex(int tag,
|
||
int *oid, uint32_t *nodes, size_t *nodes_count,
|
||
const uint8_t **value, size_t *valuelen,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
/*
|
||
EDIPartyName ::= SEQUENCE {
|
||
nameAssigner [0] DirectoryString OPTIONAL,
|
||
partyName [1] DirectoryString }
|
||
*/
|
||
int x509_edi_party_name_to_der_ex(
|
||
int tag,
|
||
int assigner_tag, const char *assigner, size_t assigner_len,
|
||
int party_name_tag, const char *party_name, size_t party_name_len,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_edi_party_name_from_der_ex(
|
||
int tag,
|
||
int *assigner_tag, const char **assigner, size_t *assigner_len,
|
||
int *party_name_tag, const char **party_name, size_t *party_name_len,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
/*
|
||
GeneralName ::= CHOICE {
|
||
otherName [0] OtherName,
|
||
rfc822Name [1] IA5String,
|
||
dNSName [2] IA5String,
|
||
x400Address [3] ORAddress,
|
||
directoryName [4] Name,
|
||
ediPartyName [5] EDIPartyName,
|
||
uniformResourceIdentifier [6] IA5String,
|
||
iPAddress [7] OCTET STRING,
|
||
registeredID [8] OBJECT IDENTIFIER
|
||
}
|
||
*/
|
||
enum {
|
||
X509_gn_otherName = 0,
|
||
X509_gn_rfc822Name,
|
||
X509_gn_dnsName,
|
||
X509_gn_x400Address,
|
||
X509_gn_directoryName,
|
||
X509_gn_ediPartyName,
|
||
X509_gn_uniformResourceIdentifier,
|
||
X509_gn_ipAddress,
|
||
X509_gn_registeredID,
|
||
};
|
||
|
||
int x509_general_name_to_der(int choice, const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen);
|
||
int x509_general_name_from_der(int *choice, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
|
||
|
||
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[256];
|
||
} X509_GENERAL_NAMES;
|
||
|
||
int x509_general_names_add_item(X509_GENERAL_NAMES *a, int choice, const uint8_t *data, size_t datalen);
|
||
int x509_general_names_get_next_item(const X509_GENERAL_NAMES *a, const uint8_t **next,
|
||
int *choice, const uint8_t **data, size_t *datalen);
|
||
|
||
#define x509_general_names_to_der(a,d,dl) \
|
||
asn1_sequence_to_der((a)->data,(a)->datalen,d,dl)
|
||
|
||
#define x509_general_names_from_der(a,d,dl) \
|
||
asn1_sequence_copy_from_der((a)->data,&((a)->datalen),d,dl)
|
||
|
||
#define x509_implicit_general_names_to_der(i,a,d,dl) \
|
||
asn1_type_to_der(ASN1_TAG_EXPLICIT(i),(a)->data,(a)->datalen,d,dl)
|
||
|
||
#define x509_implicit_general_names_from_der(i,a,d,dl) \
|
||
asn1_type_copy_from_der(ASN1_TAG_EXPLICIT(i),256,(a)->data,&((a)->datalen),d,dl)
|
||
|
||
|
||
/*
|
||
Extension 1
|
||
AuthorityKeyIdentifier ::= SEQUENCE {
|
||
keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL,
|
||
authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL,
|
||
authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
|
||
}
|
||
在验证证书时,签名方公钥是通过 issuer 在备选的CA证书列表中检索得到的
|
||
但是某些CA可能存在一个同一个名字对应了多个证书,因此需要一个格外的公钥ID
|
||
也许我们可以对所有这种SEQUENCE OF类型的都支持一个IMPLICIT
|
||
|
||
用于从多个subject同名的CA证书中挑选出需要的证书
|
||
|
||
* 如果这些同名CA证书中使用的公钥不同,那么这些公钥的key_id不同
|
||
* 如果这些同名CA证书(不是根CA证书)是由不同的上级CA签发,那么可以由issuer来区分
|
||
* 如果这些同名CA证书的序列号
|
||
|
||
|
||
AuthorityKeyIdentifier 扩展中包含签发该证书的上级CA证书的部分信息
|
||
*/
|
||
|
||
int x509_authority_key_identifier_to_der(
|
||
const uint8_t *keyid, size_t keyid_len,
|
||
const X509_GENERAL_NAMES *issuer,
|
||
const uint8_t *serial_number, size_t serial_number_len,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_authority_key_identifier_from_der(
|
||
const uint8_t **keyid, size_t *keyid_len,
|
||
X509_GENERAL_NAMES *issuer,
|
||
const uint8_t **serial_number, size_t *serial_number_len,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
int x509_certificate_set_authority_key_identifier(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const uint8_t *keyid, size_t keyid_len,
|
||
const X509_GENERAL_NAMES *issuer,
|
||
const uint8_t *serial_number, size_t serial_number_len);
|
||
|
||
int x509_certificate_get_authority_key_identifier(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
const uint8_t **keyid, size_t *keyid_len,
|
||
X509_GENERAL_NAMES *issuer,
|
||
const uint8_t **serial_number, size_t *serial_number_len);
|
||
|
||
/*
|
||
Extension 2
|
||
SubjectKeyIdentifier ::= OCTET STRING
|
||
*/
|
||
int x509_certificate_set_subject_key_identifier(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const uint8_t *keyid, size_t keyid_len);
|
||
|
||
// keyid = sm3(uncompressed_sm2_public_key_point)
|
||
int x509_certificate_generate_subject_key_identifier(X509_CERTIFICATE *cert,
|
||
int is_critical);
|
||
|
||
int x509_certificate_get_subject_key_identifier(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
const uint8_t **keyid, size_t *keyid_len);
|
||
|
||
|
||
int x509_subject_key_identifier_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
|
||
|
||
|
||
/*
|
||
Extension 3 KeyUsage
|
||
|
||
KeyUsage ::= BIT STRING {
|
||
digitalSignature (0),
|
||
nonRepudiation (1), -- recent editions of X.509 have
|
||
-- renamed this bit to contentCommitment
|
||
keyEncipherment (2),
|
||
dataEncipherment (3),
|
||
keyAgreement (4),
|
||
keyCertSign (5),
|
||
cRLSign (6),
|
||
encipherOnly (7),
|
||
decipherOnly (8) }
|
||
*/
|
||
enum X509_KeyUsage {
|
||
X509_ku_digital_signature = 0,
|
||
X509_ku_non_repudiation, // -- renamed this bit to contentCommitment
|
||
X509_ku_key_encipherment,
|
||
X509_ku_data_encipherment,
|
||
X509_ku_key_agreement,
|
||
X509_ku_key_cert_sign,
|
||
X509_ku_crl_sign,
|
||
X509_ku_encipher_only,
|
||
X509_ku_decipher_only,
|
||
};
|
||
|
||
int x509_certificate_set_key_usage(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
int usage_bits);
|
||
|
||
int x509_certificate_get_key_usage(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
int *usage_bits);
|
||
|
||
|
||
// Extension 4 CertificatePolicies
|
||
|
||
/*
|
||
DisplayText ::= CHOICE {
|
||
ia5String IA5String (SIZE (1..200)),
|
||
visibleString VisibleString (SIZE (1..200)),
|
||
bmpString BMPString (SIZE (1..200)),
|
||
utf8String UTF8String (SIZE (1..200)) }
|
||
*/
|
||
int x509_display_text_to_der(int tag, const char *text, size_t textlen, uint8_t **out, size_t *outlen);
|
||
int x509_display_text_from_der(int *tag, const char **text, size_t *textlen, const uint8_t **in, size_t *inlen);
|
||
|
||
|
||
/*
|
||
NoticeReference ::= SEQUENCE {
|
||
organization DisplayText,
|
||
noticeNumbers SEQUENCE OF INTEGER }
|
||
*/
|
||
int x509_notice_reference_to_der(
|
||
int organization_tag, const char *organization, size_t organization_len,
|
||
const int *notice_numbers, size_t notice_numbers_count,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_notice_reference_from_der(
|
||
int *organization_tag, const char **organization, size_t *organization_len,
|
||
int *notice_numbers, size_t *notice_numbers_count,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
/*
|
||
UserNotice ::= SEQUENCE {
|
||
noticeRef NoticeReference OPTIONAL,
|
||
explicitText DisplayText OPTIONAL }
|
||
*/
|
||
int x509_user_notice_to_der(
|
||
const uint8_t *notice_ref_der, size_t notice_ref_der_len,
|
||
int explicit_text_tag, const char *explicit_text, size_t explicit_text_len,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_user_notice_from_der(
|
||
const uint8_t **notice_ref_der, size_t *notice_ref_der_len,
|
||
int *explicit_text_tag, const char **explicit_text, size_t *explicit_text_len,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
/*
|
||
PolicyQualifierInfo ::= SEQUENCE {
|
||
policyQualifierId PolicyQualifierId,
|
||
qualifier ANY DEFINED BY policyQualifierId }
|
||
|
||
switch(policyQualifierId)
|
||
case id-qt-cps : qualifier ::= IA5String
|
||
case id-qt-unotice : qualifier ::= UserNotice
|
||
*/
|
||
int x509_policy_qualifier_info_to_der(int oid,
|
||
const uint8_t *qualifier, size_t qualifier_len,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_policy_qualifier_info_from_der(int *oid,
|
||
const uint8_t **qualifier, size_t *qualifier_len,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
/*
|
||
PolicyInformation ::= SEQUENCE {
|
||
policyIdentifier CertPolicyId,
|
||
policyQualifiers SEQUENCE SIZE (1..MAX) OF
|
||
PolicyQualifierInfo OPTIONAL }
|
||
|
||
CertPolicyId ::= OBJECT IDENTIFIER
|
||
*/
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[256];
|
||
} X509_POLICY_QUALIFIER_INFOS;
|
||
|
||
int x509_policy_qualifier_infos_add_item(X509_POLICY_QUALIFIER_INFOS *a,
|
||
int oid, const uint8_t *qualifier, size_t qualifier_len);
|
||
|
||
int x509_policy_qualifier_infos_get_next_item(const X509_POLICY_QUALIFIER_INFOS *a, const uint8_t **next,
|
||
int *oid, const uint8_t **qualifier, size_t *qualifier_len);
|
||
|
||
#define x509_policy_qualifier_infos_to_der(a,d,dl) \
|
||
asn1_sequence_to_der((a)->data,(a)->datalen,d,dl)
|
||
|
||
#define x509_policy_qualifier_infos_from_der(a,d,dl) \
|
||
asn1_sequence_copy_from_der(256, (a)->data,&((a)->datalen),d,dl)
|
||
|
||
int x509_policy_information_to_der(
|
||
int oid, const uint32_t *nodes, size_t nodes_count,
|
||
const X509_POLICY_QUALIFIER_INFOS *qualifiers,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_policy_information_from_der(
|
||
int *oid, uint32_t *nodes, size_t *nodes_count,
|
||
X509_POLICY_QUALIFIER_INFOS *qualifiers,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
/*
|
||
Extension 4 Certificate Policies
|
||
CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
|
||
*/
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[1024];
|
||
} X509_CERTIFICATE_POLICIES;
|
||
|
||
int x509_certificate_policies_add_item(X509_CERTIFICATE_POLICIES *a,
|
||
int oid, const uint32_t *nodes, size_t nodes_count,
|
||
const X509_POLICY_QUALIFIER_INFOS *qualifiers);
|
||
|
||
int x509_certificate_policies_get_next_item(const X509_CERTIFICATE_POLICIES *a, const uint8_t **next,
|
||
int *oid, const uint32_t *nodes, size_t *nodes_count,
|
||
X509_POLICY_QUALIFIER_INFOS *qualifiers);
|
||
|
||
#define x509_certificate_policies_to_der(a,d,dl) \
|
||
asn1_sequence_to_der((a)->data,(a)->datalen,d,dl)
|
||
|
||
#define x509_certificate_policies_from_der(a,d,dl) \
|
||
asn1_sequence_copy_from_der(1024, (a)->data,&((a)->datalen),d,dl)
|
||
|
||
|
||
|
||
int x509_certificate_set_certificate_policies(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const X509_CERTIFICATE_POLICIES *policies);
|
||
|
||
int x509_certificate_get_certificate_policies(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
X509_CERTIFICATE_POLICIES *policies);
|
||
|
||
|
||
|
||
// Extension 5. Policy Mappings
|
||
|
||
/*
|
||
PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
|
||
issuerDomainPolicy CertPolicyId,
|
||
subjectDomainPolicy CertPolicyId }
|
||
*/
|
||
int x509_policy_mapping_to_der(
|
||
int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_count,
|
||
int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_count,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_policy_mapping_from_der(
|
||
int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_count,
|
||
int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_count,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[1024];
|
||
} X509_POLICY_MAPPINGS;
|
||
|
||
int x509_policy_mappings_add_item(X509_POLICY_MAPPINGS *a,
|
||
int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_count,
|
||
int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_count);
|
||
int x509_policy_mappings_get_next_item(const X509_POLICY_MAPPINGS *a, const uint8_t **next,
|
||
uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_count,
|
||
uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_count);
|
||
|
||
#define x509_policy_mappings_to_der(a,d,dl) \
|
||
asn1_sequence_to_der((a)->data,(a)->datalen,d,dl)
|
||
|
||
#define x509_policy_mappings_from_der(a,d,dl) \
|
||
asn1_sequence_copy_from_der(1024,(a)->data,&((a)->datalen),d,dl)
|
||
|
||
|
||
int x509_certificate_set_policy_mappings(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const X509_POLICY_MAPPINGS *mappings);
|
||
|
||
int x509_certificate_get_policy_mappings(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
X509_POLICY_MAPPINGS *mappings);
|
||
|
||
|
||
// Extension 6 Subject Alternative Names
|
||
// SubjectAltName ::= GeneralNames
|
||
|
||
int x509_certificate_set_subject_alt_name(X509_CERTIFICATE *a,
|
||
int is_critical,
|
||
const X509_GENERAL_NAMES *name);
|
||
|
||
int x509_certificate_get_subject_alt_name(const X509_CERTIFICATE *a,
|
||
int *is_critical,
|
||
X509_GENERAL_NAMES *name);
|
||
|
||
|
||
// Extension 7 Issuer Alternative Name
|
||
// IssuerAltName ::= GeneralNames
|
||
|
||
int x509_certificate_set_issuer_alt_name(X509_CERTIFICATE *a,
|
||
int is_critical,
|
||
const X509_GENERAL_NAMES *name);
|
||
|
||
int x509_certificate_get_issuer_alt_name(X509_CERTIFICATE *a,
|
||
int *is_critical,
|
||
X509_GENERAL_NAMES *name);
|
||
|
||
// Extension 8. Subject Directory Attributes
|
||
/*
|
||
SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
|
||
|
||
Attribute ::= SEQUENCE {
|
||
type OBJECT IDENTIFIER,
|
||
values SET OF AttributeValue }
|
||
-- at least one value is required
|
||
|
||
AttributeValue ::= ANY
|
||
|
||
Conforming CAs MUST mark this extension as non-critical.
|
||
*/
|
||
int x509_attribute_to_der(
|
||
int oid, const uint32_t *nodes, size_t nodes_count,
|
||
const uint8_t *values, size_t valueslen,
|
||
uint8_t **out, size_t *outlen);
|
||
int x509_attribute_from_der(
|
||
int *oid, uint32_t *nodes, size_t *nodes_count,
|
||
const uint8_t **values, size_t *valueslen,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[128];
|
||
} X509_ATTRIBUTES;
|
||
|
||
int x509_attributes_add_item(X509_ATTRIBUTES *a,
|
||
int oid, const uint32_t *nodes, size_t nodes_count,
|
||
const uint8_t *values, size_t valueslen);
|
||
|
||
int x509_attributes_get_next_item(const X509_ATTRIBUTES *a, const uint8_t **next,
|
||
int *oid, uint32_t *nodes, size_t *nodes_count,
|
||
const uint8_t **data, size_t *datalen);
|
||
|
||
#define x509_attributes_to_der(a,d,dl) \
|
||
asn1_sequence_to_der((a)->data,(a)->datalen,d,dl)
|
||
|
||
#define x509_attributes_from_der(a,d,dl) \
|
||
asn1_sequence_copy_from_der(128,(a)->data,&((a)->datalen),d,dl)
|
||
|
||
|
||
int x509_certificate_set_subject_directory_attributes(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const X509_ATTRIBUTES *attrs);
|
||
|
||
int x509_certificate_get_subject_directory_attributes(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
X509_ATTRIBUTES *attrs);
|
||
|
||
|
||
|
||
|
||
// Extension 9. Basic Constraints
|
||
/*
|
||
BasicConstraints ::= SEQUENCE {
|
||
cA BOOLEAN DEFAULT FALSE,
|
||
pathLenConstraint INTEGER (0..MAX) OPTIONAL }
|
||
*/
|
||
|
||
int x509_basic_constraints_to_der(int is_ca_cert, // 必须设置为 0 或 1,如果设为 0 那么不编码
|
||
int cert_chain_maxlen, // -1 means omitted,FIXME: 应该设置一个最大值
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_basic_constraints_from_der(int *is_ca_cert, int *cert_chain_maxlen, const uint8_t **in, size_t *inlen);
|
||
|
||
int x509_certificate_set_basic_constraints(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
int is_ca_cert,
|
||
int cert_chain_maxlen);
|
||
|
||
int x509_certificate_get_basic_constraints(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
int *is_ca_cert,
|
||
int *cert_chain_maxlen);
|
||
|
||
int x509_basic_constraints_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
|
||
int x509_key_usage_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
|
||
int x509_authority_key_identifier_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
|
||
|
||
|
||
|
||
// Extension 10. Name Constraints
|
||
/*
|
||
NameConstraints ::= SEQUENCE {
|
||
permittedSubtrees [0] GeneralSubtrees OPTIONAL,
|
||
excludedSubtrees [1] GeneralSubtrees OPTIONAL }
|
||
|
||
GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
|
||
|
||
GeneralSubtree ::= SEQUENCE {
|
||
base GeneralName,
|
||
minimum [0] BaseDistance DEFAULT 0,
|
||
maximum [1] BaseDistance OPTIONAL }
|
||
|
||
BaseDistance ::= INTEGER (0..MAX)
|
||
*/
|
||
int x509_general_subtree_to_der(
|
||
int base_choise, const uint8_t *base_data, size_t base_datalen,
|
||
int minimum,
|
||
int maximum,
|
||
uint8_t **out, size_t *outlen);
|
||
int x509_general_subtree_from_der(
|
||
int *base_choise, const uint8_t **base_data, size_t *base_datalen,
|
||
int *minimum,
|
||
int *maximum,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[128];
|
||
} X509_GENERAL_SUBTREES;
|
||
|
||
int x509_general_subtrees_add_item(X509_GENERAL_SUBTREES *a,
|
||
int base_choise, const uint8_t *base_data, size_t base_datalen,
|
||
int minimum,
|
||
int maximum);
|
||
int x509_general_subtrees_get_next_item(const X509_GENERAL_SUBTREES *a, const uint8_t **next,
|
||
int *base_choise, const uint8_t **base_data, size_t *base_datalen,
|
||
int *minimum,
|
||
int *maximum);
|
||
|
||
int x509_general_subtrees_to_der_ex(int tag, const X509_GENERAL_SUBTREES *a, uint8_t **out, size_t *outlen);
|
||
int x509_general_subtrees_from_der_ex(int tag, X509_GENERAL_SUBTREES *a, const uint8_t **in, size_t *inlen);
|
||
|
||
#define x509_general_subtrees_to_der(a,d,dl) \
|
||
asn1_sequence_to_der((a)->data,(a)->datalen,d,dl)
|
||
|
||
#define x509_general_subtrees_from_der(a,d,dl) \
|
||
asn1_sequence_copy_from_der(128,(a)->data,&((a)->datalen),d,dl)
|
||
|
||
int x509_name_constraints_to_der(
|
||
const X509_GENERAL_SUBTREES *permitted_subtrees,
|
||
const X509_GENERAL_SUBTREES *excluded_subtrees,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_name_constraints_from_der(
|
||
X509_GENERAL_SUBTREES *permitted_subtrees,
|
||
X509_GENERAL_SUBTREES *excluded_subtrees,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
int x509_certificate_set_name_constraints(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const X509_GENERAL_SUBTREES *permitted_subtrees,
|
||
const X509_GENERAL_SUBTREES *excluded_subtrees);
|
||
|
||
int x509_certificate_get_name_constraints(X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
X509_GENERAL_SUBTREES *permitted_subtrees,
|
||
X509_GENERAL_SUBTREES *excluded_subtrees);
|
||
|
||
|
||
|
||
// Extension 11. Policy Constraints
|
||
/*
|
||
PolicyConstraints ::= SEQUENCE {
|
||
requireExplicitPolicy [0] SkipCerts OPTIONAL,
|
||
inhibitPolicyMapping [1] SkipCerts OPTIONAL }
|
||
|
||
SkipCerts ::= INTEGER (0..MAX)
|
||
*/
|
||
|
||
int x509_policy_constraints_to_der(
|
||
int require_explicit_policy,
|
||
int inhibit_policy_mapping,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_policy_constraints_from_der(
|
||
int *require_explicit_policy,
|
||
int *inhibit_policy_mapping,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
int x509_certificate_set_policy_constraints(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
int require_explicit_policy,
|
||
int inhibit_policy_mapping);
|
||
|
||
int x509_certificate_get_policy_constraints(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
int *requireExplicitPolicy,
|
||
int *inhibitPolicyMapping);
|
||
|
||
|
||
/*
|
||
12. Extended Key Usage
|
||
|
||
ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
|
||
KeyPurposeId ::= OBJECT IDENTIFIER
|
||
|
||
*/
|
||
int x509_key_purpose_from_name(int *oid, const char *name);
|
||
const char *x509_key_purpose_name(int oid);
|
||
const char *x509_key_purpose_text(int oid);
|
||
int x509_key_purpose_to_der(int oid, uint8_t **out, size_t *outlen);
|
||
int x509_key_purpose_from_der(int *oid, const uint8_t **in, size_t *inlen);
|
||
int x509_ext_key_usage_to_der(const int *oids, size_t oids_count, uint8_t **out, size_t *outlen);
|
||
int x509_ext_key_usage_from_der(int *oids, size_t *oids_count, const uint8_t **in, size_t *inlen);
|
||
|
||
int x509_certificate_set_ext_key_usage(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const int *key_purpose_oids, size_t key_purpose_oids_count);
|
||
|
||
int x509_certificate_get_ext_key_usage(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
int *key_purpose_oids, size_t *key_purpose_oids_count);
|
||
|
||
/*
|
||
|
||
13. CRL Distribution Points
|
||
|
||
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
|
||
|
||
DistributionPoint ::= SEQUENCE {
|
||
distributionPoint [0] DistributionPointName OPTIONAL,
|
||
reasons [1] ReasonFlags OPTIONAL,
|
||
cRLIssuer [2] GeneralNames OPTIONAL }
|
||
|
||
DistributionPointName ::= CHOICE {
|
||
fullName [0] GeneralNames,
|
||
nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
|
||
|
||
由于 GeneralNames 是存储类型,因此 DistributionPointName 也是存储类型
|
||
|
||
ReasonFlags ::= BIT STRING {
|
||
unused (0),
|
||
keyCompromise (1),
|
||
cACompromise (2),
|
||
affiliationChanged (3),
|
||
superseded (4),
|
||
cessationOfOperation (5),
|
||
certificateHold (6),
|
||
privilegeWithdrawn (7),
|
||
aACompromise (8) }
|
||
*/
|
||
enum {
|
||
X509_rf_unused = 0,
|
||
X509_rf_keyCompromise,
|
||
X509_rf_caCompromise,
|
||
X509_rf_affiliationChanged,
|
||
X509_rf_superseded,
|
||
X509_rf_cessationOfOperation,
|
||
X509_rf_certificateHold,
|
||
X509_rf_privilegeWithdrawn,
|
||
X509_rf_aaCompromise,
|
||
};
|
||
|
||
typedef struct {
|
||
int choice;
|
||
union {
|
||
X509_GENERAL_NAMES full_name; // [0] IMPLICIT
|
||
X509_RDN relative_name; // [1] IMPLICIT
|
||
} u;
|
||
} X509_DISTRIBUTION_POINT_NAME;
|
||
|
||
int x509_distribution_point_name_to_der_ex(
|
||
int tag,
|
||
const X509_DISTRIBUTION_POINT_NAME *a,
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_distribution_point_name_from_der_ex(
|
||
int tag,
|
||
X509_DISTRIBUTION_POINT_NAME *a,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
|
||
int x509_distribution_point_to_der( // DistributionPoint
|
||
const X509_DISTRIBUTION_POINT_NAME *dist_point_name, // [0] EXPLICIT OPTIONAL
|
||
int reason_bits, // [1] IMPLICIT OPTIONAL
|
||
const X509_GENERAL_NAMES *crl_issuer, // [2] IMPLICIT OPTIONAL
|
||
uint8_t **out, size_t *outlen);
|
||
|
||
int x509_distribution_point_from_der(
|
||
X509_DISTRIBUTION_POINT_NAME *dist_point_name,
|
||
int *reason_bits,
|
||
X509_GENERAL_NAMES *crl_issuer,
|
||
const uint8_t **in, size_t *inlen);
|
||
|
||
typedef struct {
|
||
size_t datalen;
|
||
uint8_t data[128];
|
||
} X509_CRL_DISTRIBUTION_POINTS;
|
||
|
||
int x509_crl_distribution_points_add_item(X509_CRL_DISTRIBUTION_POINTS *a,
|
||
const X509_DISTRIBUTION_POINT_NAME *dist_point_name,
|
||
int reason_bits,
|
||
const X509_GENERAL_NAMES *crl_issuer);
|
||
int x509_crl_distribution_points_get_next_item(const X509_CRL_DISTRIBUTION_POINTS *a,
|
||
const uint8_t **next,
|
||
X509_DISTRIBUTION_POINT_NAME *distribution_point,
|
||
int *reasons,
|
||
X509_GENERAL_NAMES *crl_issuer);
|
||
int x509_crl_distribution_points_to_der(const X509_CRL_DISTRIBUTION_POINTS *a, uint8_t **out, size_t *outlen);
|
||
int x509_crl_distribution_points_from_der(X509_CRL_DISTRIBUTION_POINTS *a, const uint8_t **in, size_t *inlen);
|
||
|
||
int x509_certificate_set_crl_distribution_points(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const X509_CRL_DISTRIBUTION_POINTS *crl_dist_points);
|
||
|
||
int x509_certificate_get_crl_distribution_points(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
X509_CRL_DISTRIBUTION_POINTS *crl_dist_points);
|
||
|
||
|
||
/*
|
||
14. Inhibit anyPolicy
|
||
|
||
id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
|
||
|
||
InhibitAnyPolicy ::= SkipCerts
|
||
|
||
SkipCerts ::= INTEGER (0..MAX)
|
||
*/
|
||
int x509_certificate_set_inhibit_any_policy(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
int skip_certs);
|
||
int x509_certificate_get_inhibit_any_policy(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
int *skip_certs);
|
||
|
||
/*
|
||
15. Freshest CRL (a.k.a. Delta CRL Distribution Point)
|
||
FreshestCRL ::= CRLDistributionPoints
|
||
*/
|
||
int x509_certificate_set_freshest_crl(X509_CERTIFICATE *cert,
|
||
int is_critical,
|
||
const X509_CRL_DISTRIBUTION_POINTS *crl_dist_points);
|
||
int x509_certificate_get_freshest_crl(const X509_CERTIFICATE *cert,
|
||
int *is_critical,
|
||
X509_CRL_DISTRIBUTION_POINTS *crl_dist_points);
|
||
|
||
|
||
#define X509_ub_name 32768
|
||
#define X509_ub_common_name 64
|
||
#define X509_ub_locality_name 128
|
||
#define X509_ub_state_name 128
|
||
#define X509_ub_organization_name 64
|
||
#define X509_ub_organizational_unit_name 64
|
||
#define X509_ub_title 64
|
||
#define X509_ub_serial_number 64
|
||
#define X509_ub_match 128
|
||
#define X509_ub_emailaddress_length 255
|
||
#define X509_ub_common_name_length 64
|
||
#define X509_ub_country_name_alpha_length 2
|
||
#define X509_ub_country_name_numeric_length 3
|
||
#define X509_ub_domain_defined_attributes 4
|
||
#define X509_ub_domain_defined_attribute_type_length 8
|
||
#define X509_ub_domain_defined_attribute_value_length 128
|
||
#define X509_ub_domain_name_length 16
|
||
#define X509_ub_extension_attributes 256
|
||
#define X509_ub_e163_4_number_length 15
|
||
#define X509_ub_e163_4_sub_address_length 40
|
||
#define X509_ub_generation_qualifier_length 3
|
||
#define X509_ub_given_name_length 16
|
||
#define X509_ub_initials_length 5
|
||
#define X509_ub_integer_options 256
|
||
#define X509_ub_numeric_user_id_length 32
|
||
#define X509_ub_organization_name_length 64
|
||
#define X509_ub_organizational_unit_name_length 32
|
||
#define X509_ub_organizational_units 4
|
||
#define X509_ub_pds_name_length 16
|
||
#define X509_ub_pds_parameter_length 30
|
||
#define X509_ub_pds_physical_address_lines 6
|
||
#define X509_ub_postal_code_length 16
|
||
#define X509_ub_pseudonym 128
|
||
#define X509_ub_surname_length 40
|
||
#define X509_ub_terminal_id_length 24
|
||
#define X509_ub_unformatted_address_length 180
|
||
#define X509_ub_x121_address_length 16
|
||
|
||
|
||
typedef struct {
|
||
int version;
|
||
X509_NAME subject;
|
||
X509_PUBLIC_KEY_INFO subject_public_key_info;
|
||
} X509_CERT_REQUEST_INFO;
|
||
|
||
int x509_cert_request_info_to_der(const X509_CERT_REQUEST_INFO *a, uint8_t **out, size_t *outlen);
|
||
int x509_cert_request_info_from_der(X509_CERT_REQUEST_INFO *a, const uint8_t **in, size_t *inlen);
|
||
|
||
typedef struct {
|
||
X509_CERT_REQUEST_INFO req_info;
|
||
int signature_algor;
|
||
uint8_t signature[128];
|
||
size_t signature_len;
|
||
} X509_CERT_REQUEST;
|
||
|
||
int x509_cert_request_set_sm2(X509_CERT_REQUEST *a, const X509_NAME *subject, const SM2_KEY *sm2_key);
|
||
int x509_cert_request_sign_sm2(X509_CERT_REQUEST *a, const SM2_KEY *sm2_key);
|
||
int x509_cert_request_verify(const X509_CERT_REQUEST *a);
|
||
#define x509_cert_request_set(a,subj,pk) x509_cert_request_set_sm2((a),(subj),(pk))
|
||
#define x509_cert_request_sign(a,sk) x509_cert_request_sign_sm2((a),(sk))
|
||
|
||
int x509_cert_request_to_der(const X509_CERT_REQUEST *a, uint8_t **out, size_t *outlen);
|
||
int x509_cert_request_to_pem(const X509_CERT_REQUEST *a, FILE *fp);
|
||
int x509_cert_request_from_der(X509_CERT_REQUEST *a, const uint8_t **in, size_t *inlen);
|
||
int x509_cert_request_from_pem(X509_CERT_REQUEST *a, FILE *fp);
|
||
int x509_cert_request_print(FILE *fp, const X509_CERT_REQUEST *a, int format, int indent);
|
||
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif
|