Update CRL functions and tools

This commit is contained in:
Zhi Guan
2023-01-25 22:39:12 +08:00
parent c6ca4dd37b
commit c4c11ffe6b
21 changed files with 1854 additions and 527 deletions

View File

@@ -99,9 +99,11 @@ set(tools
tools/certgen.c
tools/certparse.c
tools/certverify.c
tools/certrevoke.c
tools/reqgen.c
tools/reqparse.c
tools/reqsign.c
tools/crlgen.c
tools/crlparse.c
tools/crlverify.c
tools/cmssign.c

33
demos/wget.c Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/http.h>
#include <gmssl/error.h>
int main(int argc, char **argv)
{
uint8_t buf[65536];
uint8_t *content;
size_t contentlen;
if (argc < 2) {
printf("usage: %s <uri>\n", argv[0]);
return 1;
}
if (http_get(argv[1], buf, sizeof(buf), &content, &contentlen) != 1) {
error_print();
return -1;
}
fwrite(content, contentlen, 1, stdout);
return 0;
}

View File

@@ -260,6 +260,7 @@ int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, co
#define ASN1_UTC_TIME_STRLEN (sizeof("YYMMDDHHMMSSZ")-1)
#define ASN1_GENERALIZED_TIME_STRLEN (sizeof("YYYYMMDDHHMMSSZ")-1)
#define ASN1_GENERALIZED_TIME_MAX_SIZE (2 + ASN1_GENERALIZED_TIME_STRLEN)
int asn1_time_to_str(int utc_time, time_t timestamp, char *str);
int asn1_time_from_str(int utc_time, time_t *timestamp, const char *str);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ extern "C" {
int file_size(FILE *fp, size_t *size);
int file_read_all(const char *file, uint8_t **out, size_t *outlen);
#ifdef __cplusplus

View File

@@ -19,8 +19,8 @@ extern "C" {
int http_parse_uri(const char *uri, char host[128], int *port, char path[256]);
int http_parse_response(uint8_t *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left);
int http_get(const char *uri, uint8_t *buf, size_t buflen, uint8_t **content, size_t *contentlen);
int http_parse_response(char *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left);
int http_get(const char *uri, uint8_t *buf, size_t *contentlen, size_t buflen);
#ifdef __cplusplus

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -205,8 +205,7 @@ enum {
#define oid_cnt(nodes) (sizeof(nodes)/sizeof(int))
#define oid_cnt(nodes) (sizeof(nodes)/sizeof((nodes)[0]))

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -323,6 +323,7 @@ typedef struct {
int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen);
int sm2_sign_finish_fixlen(SM2_SIGN_CTX *ctx, size_t siglen, uint8_t *sig);
int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
int sm2_verify_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);

View File

@@ -268,6 +268,18 @@ int x509_certificate_from_der(
int *signature_algor,
const uint8_t **sig, size_t *siglen,
const uint8_t **in, size_t *inlen);
int x509_signed_to_der(
const uint8_t *tbs, size_t tbslen,
int signature_algor,
const uint8_t *sig, size_t siglen,
uint8_t **out, size_t *outlen);
int x509_signed_from_der(
const uint8_t **tbs, size_t *tbslen,
int *signature_algor,
const uint8_t **sig, size_t *siglen,
const uint8_t **in, size_t *inlen);
int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
// x509_cert functions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -13,17 +13,15 @@
#define GMSSL_X509_CRL_H
#include <time.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
X509 CRL Public API
*/
/*
CRLReason ::= ENUMERATED
@@ -46,34 +44,41 @@ const char *x509_crl_reason_name(int reason);
int x509_crl_reason_from_name(int *reason, const char *name);
int x509_crl_reason_to_der(int reason, uint8_t **out, size_t *outlen);
int x509_crl_reason_from_der(int *reason, const uint8_t **in, size_t *inlen);
int x509_implicit_crl_reason_from_der(int index, int *reason, const uint8_t **in, size_t *inlen);
/*
CRL Entry Extensions:
OID_ce_crl_reasons ENUMERATED
OID_ce_invalidity_date GeneralizedTime
OID_ce_certificate_issuer SEQUENCE GeneralNames
OID_ce_crl_reasons ENUMERATED non-critical
OID_ce_invalidity_date GeneralizedTime non-critical
OID_ce_certificate_issuer GeneralNames MUST critical
*/
const char *x509_crl_entry_ext_id_name(int oid);
int x509_crl_entry_ext_id_from_name(const char *name);
int x509_crl_entry_ext_id_to_der(int oid, uint8_t **out, size_t *outlen);
int x509_crl_entry_ext_id_from_der(int *oid, const uint8_t **in, size_t *inlen);
int x509_crl_entry_exts_add_reason(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
int reason);
int x509_crl_entry_exts_add_invalidity_date(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
time_t tv);
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_ext_critical_validate(int oid, int critical);
int x509_crl_reason_ext_to_der(int critical, int reason, uint8_t **out, size_t *outlen);
int x509_invalidity_date_ext_to_der(int critical, time_t date, uint8_t **out, size_t *outlen);
int x509_cert_issuer_ext_to_der(int critical, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
int x509_crl_entry_ext_from_der(int *oid, int *critical,
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_crl_entry_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_entry_exts_to_der(
int reason, time_t invalid_date, const uint8_t *cert_issuer, size_t cert_issuer_len,
uint8_t **out, size_t *outlen);
int x509_crl_entry_exts_from_der(
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_crl_entry_exts_get(const uint8_t *d, size_t dlen,
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len);
int x509_crl_entry_exts_validate(const uint8_t *d, size_t dlen);
int x509_crl_entry_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
RevokedCertificate ::= SEQUENCE {
userCertificate CertificateSerialNumber,
@@ -81,45 +86,50 @@ RevokedCertificate ::= SEQUENCE {
crlEntryExtensions Extensions OPTIONAL }
*/
int x509_revoked_cert_to_der(
const uint8_t *serial, size_t serial_len,
time_t revoke_date,
const uint8_t *entry_exts, size_t entry_exts_len,
const uint8_t *serial, size_t serial_len, time_t revoke_date,
const uint8_t *crl_entry_exts, size_t crl_entry_exts_len,
uint8_t **out, size_t *outlen);
int x509_revoked_cert_from_der(
const uint8_t **serial, size_t *serial_len,
time_t *revoke_date,
const uint8_t **entry_exts, size_t *entry_exts_len,
const uint8_t **serial, size_t *serial_len, time_t *revoke_date,
const uint8_t **crl_entry_exts, size_t *crl_entry_exts_len,
const uint8_t **in, size_t *inlen);
int x509_revoked_cert_to_der_ex(
const uint8_t *serial, size_t serial_len, time_t revoke_date,
int reason, time_t invalid_date, const uint8_t *cert_issuer, size_t cert_issuer_len,
uint8_t **out, size_t *outlen);
int x509_revoked_cert_from_der_ex(
const uint8_t **serial, size_t *serial_len, time_t *revoke_date,
int *reason, time_t *invalid_date, const uint8_t **cert_issuer, size_t *cert_issuer_len,
const uint8_t **in, size_t *inlen);
int x509_revoked_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_cert_revoke_to_der(const uint8_t *cert, size_t certlen,
time_t revoke_date, int reason, time_t invalid_date, const uint8_t *cert_issuer, size_t cert_issuer_len,
uint8_t **out, size_t *outlen);
/*
RevokedCertificates ::= SEQUENCE OF RevokedCertificate
*/
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);
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);
#define x509_revoked_certs_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
#define x509_revoked_certs_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
int x509_revoked_certs_find_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 **crl_entry_exts, size_t *crl_entry_exts_len);
int x509_revoked_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
/*
CRL Extensions:
OID_ce_authority_key_identifier SEQUENCE AuthorityKeyIdentifier
OID_ce_issuer_alt_name SEQUENCE GeneralNames
OID_ce_crl_number INTEGER
OID_ce_delta_crl_indicator INTEGER
OID_ce_issuing_distribution_point SEQUENCE IssuingDistributionPoint
OID_ce_authority_key_identifier AuthorityKeyIdentifier critical or non-critical
OID_ce_issuer_alt_name GeneralNames SHOULD non-critical
OID_ce_crl_number INTEGER MUST non-critical
OID_ce_delta_crl_indicator INTEGER MUST critical
OID_ce_issuing_distribution_point IssuingDistributionPoint critical
OID_ce_freshest_crl CRLDistributionPoints MUST non-critical
OID_pe_authority_info_access AccessDescriptions MUST non-critical
*/
const char *x509_crl_ext_id_name(int oid);
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);
int x509_crl_ext_id_from_der_ex(int *oid, uint32_t *nodes, size_t *nodes_cnt, const uint8_t **in, size_t *inlen);
/*
IssuingDistributionPoint ::= SEQUENCE {
@@ -132,7 +142,7 @@ IssuingDistributionPoint ::= SEQUENCE {
*/
int x509_issuing_distribution_point_to_der(
int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
const char *dist_point_uri, size_t dist_point_uri_len,
int only_contains_user_certs,
int only_contains_ca_certs,
int only_some_reasons,
@@ -147,6 +157,15 @@ int x509_issuing_distribution_point_from_der(
int *indirect_crl,
int *only_contains_attr_certs,
const uint8_t **in, size_t *inlen);
int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_ext_critical_validate(int oid, int critical);
int x509_crl_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen);
int x509_crl_ext_from_der_ex(int *oid, uint32_t *nodes, size_t *nodes_cnt,
int *critical, const uint8_t **val, size_t *vlen,
const uint8_t **in, size_t *inlen);
int x509_crl_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_exts_add_authority_key_identifier(
uint8_t *exts, size_t *extslen, size_t maxlen,
@@ -158,6 +177,9 @@ int x509_crl_exts_add_issuer_alt_name(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
const uint8_t *d, size_t dlen);
int x509_crl_exts_add_crl_number_ex(
uint8_t *exts, size_t *extslen, size_t maxlen,
int oid, int critical, int num);
int x509_crl_exts_add_crl_number(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
@@ -169,13 +191,22 @@ int x509_crl_exts_add_delta_crl_indicator(
int x509_crl_exts_add_issuing_distribution_point(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
const uint8_t *dist_point, size_t dist_point_len,
const char *dist_point_uri, size_t dist_point_uri_len,
int only_contains_user_certs,
int only_contains_ca_certs,
int only_some_reasons,
int indirect_crl,
int only_contains_attr_certs);
int x509_crl_exts_add_freshest_crl(
uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const char *http_uri, size_t http_urilen,
const char *ldap_uri, size_t ldap_urilen);
int x509_crl_exts_add_authority_info_acess(
uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const char *ca_issuers_uri, size_t ca_issuers_urilen,
const char *ocsp_uri, size_t ocsp_urilen);
int x509_crl_exts_validate(const uint8_t *d, size_t dlen);
#define x509_crl_exts_to_der(d,dlen,out,outlen) x509_explicit_exts_to_der(0,d,dlen,out,outlen)
#define x509_crl_exts_from_der(d,dlen,in,inlen) x509_explicit_exts_from_der(0,d,dlen,in,inlen)
int x509_crl_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
@@ -217,12 +248,8 @@ CertificateList ::= SEQUENCE {
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
*/
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);
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);
#define x509_cert_list_to_der(tbs,tbslen,sig_alg,sig,siglen,out,outlen) x509_signed_to_der(tbs,tbslen,sig_alg,sig,siglen,out,outlen)
#define x509_cert_list_from_der(tbs,tbslen,sig_alg,sig,siglen,in,inlen) x509_signed_from_der(tbs,tbslen,sig_alg,sig,siglen,in,inlen)
int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
// x509_crl_ functions
@@ -230,28 +257,34 @@ 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_to_fp(const uint8_t *a, size_t alen, FILE *fp); // 去掉这个函数
int x509_crl_from_fp(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);
int x509_crl_sign(uint8_t *crl, size_t *crl_len,
int version,
int signature_algor,
int x509_crl_sign_to_der(
int version, int sig_alg,
const uint8_t *issuer, size_t issuer_len,
time_t this_update,
time_t next_update,
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,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len);
const uint8_t *crl_exts, size_t crl_exts_len,
const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len,
uint8_t **out, size_t *outlen);
int x509_crl_from_der_ex(
int *version,
int *inner_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,
int *sig_alg, const uint8_t **sig, size_t *siglen,
const uint8_t **in, size_t *inlen);
int x509_crl_validate(const uint8_t *a, size_t alen, time_t now, const uint8_t *ca_subject, size_t ca_subject_len);
int x509_crl_verify(const uint8_t *a, size_t alen,
const SM2_KEY *sign_pub_key, const char *signer_id, size_t signer_id_len);
int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen, const uint8_t *cacert, size_t cacertlen,
const char *signer_id, size_t signer_id_len);
int x509_crl_get_details(const uint8_t *crl, size_t crl_len,
int *version,
int *inner_sig_alg,
const uint8_t **issuer, size_t *issuer_len,
time_t *this_update,
time_t *next_update,
@@ -261,15 +294,17 @@ int x509_crl_get_details(const uint8_t *crl, size_t crl_len,
const uint8_t **sig, size_t *siglen);
int x509_crl_get_issuer(const uint8_t *crl, size_t crl_len,
const uint8_t **issuer, size_t *issuer_len);
int x509_crl_get_revoked_certs(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen);
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);
int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
int x509_crl_new_from_uri(uint8_t **crl, size_t *crl_len, const char *uri, size_t urilen);
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -24,6 +24,12 @@
extern "C" {
#endif
enum {
X509_non_critical = 0,
X509_critical = 1,
};
/*
Extensions:
@@ -64,6 +70,8 @@ int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxl
int require_explicit_policy, int inhibit_policy_mapping);
int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int ca, int path_len_constraint);
int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const int *key_purposes, size_t key_purposes_cnt);
int x509_exts_add_crl_distribution_points_ex(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int oid,
const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen);
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen);
int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int skip_certs);
@@ -471,6 +479,7 @@ DistributionPointName ::= CHOICE {
nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName } -- SET OF
*/
int x509_uri_as_general_names_to_der_ex(int tag, const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
#define x509_uri_as_general_names_to_der(uri,urilen,out,outlen) x509_uri_as_general_names_to_der_ex(ASN1_TAG_SEQUENCE,uri,urilen,out,outlen)
int x509_uri_as_distribution_point_name_to_der(const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
int x509_uri_as_explicit_distribution_point_name_to_der(int index, const char *uri, size_t urilen, uint8_t **out, size_t *outlen);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -33,3 +33,31 @@ int file_size(FILE *fp, size_t *size)
*size = st.st_size;
return 1;
}
int file_read_all(const char *file, uint8_t **out, size_t *outlen)
{
int ret = -1;
FILE *fp = NULL;
size_t fsize;
uint8_t *buf = NULL;
if (!(fp = fopen(file, "r"))
|| file_size(fp, &fsize) != 1
|| (buf = malloc(fsize)) == NULL) {
error_print();
goto end;
}
if (fread(buf, 1, fsize, fp) != fsize) {
error_print();
goto end;
}
*out = buf;
*outlen = fsize;
buf = NULL;
ret = 1;
end:
if (fp) fclose(fp);
if (buf) free(buf);
return ret;
}

View File

@@ -1,5 +1,4 @@
/*
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
@@ -65,7 +64,7 @@ static int socket_recv_all(int sock, uint8_t *buf, size_t len)
return 1;
}
int http_parse_response(uint8_t *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left)
int http_parse_response(char *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left)
{
char *ok = "HTTP/1.1 200 OK\r\n";
char *p;
@@ -75,14 +74,14 @@ int http_parse_response(uint8_t *buf, size_t buflen, uint8_t **content, size_t *
error_print();
return -1;
}
if (!(p = strnstr((char *)buf, "\r\n\r\n", buflen))) {
if (!(p = strnstr(buf, "\r\n\r\n", buflen))) {
error_print();
return -1;
}
*content = (uint8_t *)(p + 4);
headerlen = *content - buf;
headerlen = *content - (uint8_t *)buf;
if (!(p = strnstr((char *)buf, "\r\nContent-Length: ", headerlen))) {
if (!(p = strnstr(buf, "\r\nContent-Length: ", headerlen))) {
error_print();
return -1;
}
@@ -104,10 +103,9 @@ int http_parse_response(uint8_t *buf, size_t buflen, uint8_t **content, size_t *
#define HTTP_GET_TEMPLATE "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "\r\n\r\n"
int http_get(const char *uri, uint8_t *buf, size_t buflen,
uint8_t **content, size_t *contentlen)
int http_get(const char *uri, uint8_t *buf, size_t *contentlen, size_t buflen)
{
char *uribuf = NULL;
int ret = -1;
char host[128];
int port;
char path[256];
@@ -116,16 +114,22 @@ int http_get(const char *uri, uint8_t *buf, size_t buflen,
tls_socket_t sock;
char get[sizeof(HTTP_GET_TEMPLATE) + sizeof(host) + sizeof(path)];
int getlen;
char response[512];
uint8_t *p;
size_t len;
size_t left;
// parse uri
// parse uri and compose request
if (http_parse_uri(uri, host, &port, path) != 1) {
error_print();
return -1;
}
if ((getlen = snprintf(get, sizeof(get), HTTP_GET_TEMPLATE, path, host)) <= 0) {
error_print();
return -1;
}
// connect
// connect and send request
if (!(hp = gethostbyname(host))) {
error_print();
return -1;
@@ -140,42 +144,36 @@ int http_get(const char *uri, uint8_t *buf, size_t buflen,
}
if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) {
error_print();
return -1;
}
// request
if ((getlen = snprintf(get, sizeof(get),
"GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"\r\n\r\n", path, host)) <= 0) {
error_print();
return -1;
goto end;
}
if (send(sock, get, strlen(get), 0) != getlen) {
error_print();
return -1;
goto end;
}
if ((len = recv(sock, response, sizeof(response), 0)) <= 0) {
error_print();
goto end;
}
// response
if ((len = recv(sock, buf, buflen, 0)) <= 0) {
// process response header and retrieve left
if (http_parse_response(response, len, &p, contentlen, &left) != 1) {
error_print();
return -1;
goto end;
}
if (http_parse_response(buf, len, content, contentlen, &left) != 1) {
error_print();
return -1;
if (!buf || buflen < *contentlen) {
ret = 0;
goto end;
}
memcpy(buf, p, *contentlen - left);
if (left) {
if (len + left > buflen) {
error_print(); // buf is not enough
return -1;
}
if (socket_recv_all(sock, buf + len, left) != 1) {
if (socket_recv_all(sock, buf + *contentlen - left, left) != 1) {
error_print();
return -1;
goto end;
}
}
ret = 1;
return 1;
end:
close(sock);
return ret;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -382,6 +382,23 @@ int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen)
return 1;
}
int sm2_sign_finish_fixlen(SM2_SIGN_CTX *ctx, size_t siglen, uint8_t *sig)
{
int ret;
uint8_t dgst[SM3_DIGEST_SIZE];
if (!ctx || !sig || !siglen) {
error_print();
return -1;
}
sm3_finish(&ctx->sm3_ctx, dgst);
if ((ret = sm2_sign_fixlen(&ctx->key, dgst, siglen, sig)) != 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)
{
if (!ctx || !key) {

View File

@@ -729,7 +729,7 @@ int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt,
if (ret < 0) error_print();
return ret;
}
*critical = 0;
*critical = 0; // FIXME: do not set default
if (x509_ext_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1
|| asn1_boolean_from_der(critical, &d, &dlen) < 0
|| asn1_octet_string_from_der(val, vlen, &d, &dlen) != 1
@@ -1041,6 +1041,48 @@ int x509_certificate_to_der(
return 1;
}
int x509_signed_to_der(
const uint8_t *tbs, size_t tbslen, // full TLV
int signature_algor,
const uint8_t *sig, size_t siglen,
uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (asn1_data_to_der(tbs, tbslen, 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_data_to_der(tbs, tbslen, 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_signed_from_der(const uint8_t **tbs, size_t *tbs_len,
int *sig_alg, const uint8_t **sig, size_t *siglen,
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 -1;
}
if (asn1_any_from_der(tbs, tbs_len, &d, &dlen) != 1
|| x509_signature_algor_from_der(sig_alg, &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_certificate_from_der(
const uint8_t **tbs, size_t *tbslen, // full TLV
int *signature_algor,
@@ -1571,6 +1613,8 @@ int x509_certs_get_cert_by_issuer_and_serial_number(
return 0;
}
// 这里面需要validate的类型是两种一种直接得到了实际值因此可以直接对实际值做验证
// 另一种是SEQUENCE OF类型本质上是完整的a,alen因此这种类型实际上可以用from_der来解析
int x509_cert_validate(const uint8_t *cert, size_t certlen, int cert_type,
int *path_len_constraints)
{

File diff suppressed because it is too large Load Diff

View File

@@ -284,23 +284,15 @@ int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen,
return 1;
}
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen,
int critical, const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen)
int x509_exts_add_crl_distribution_points_ex(uint8_t *exts, size_t *extslen, size_t maxlen,
int oid, int critical, const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen)
{
int oid = OID_ce_crl_distribution_points;
size_t curlen = *extslen;
uint8_t val[256];
uint8_t *p = val;
size_t vlen = 0;
size_t len = 0;
// The extension SHOULD be non-critical, but this profile
// RECOMMENDS support for this extension by CAs and applications.
if (critical) {
error_print();
//return -1;
}
if (x509_distribution_points_to_der(http_uri, http_urilen, ldap_uri, ldap_urilen, NULL, &len) != 1
|| asn1_length_le(len, sizeof(val)) != 1
|| x509_distribution_points_to_der(http_uri, http_urilen, ldap_uri, ldap_urilen, &p, &vlen) != 1) {
@@ -317,6 +309,18 @@ int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t
return 1;
}
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen,
int critical, const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen)
{
int oid = OID_ce_crl_distribution_points;
if (x509_exts_add_crl_distribution_points_ex(exts, extslen, maxlen,
oid, critical, http_uri, http_urilen, ldap_uri, ldap_urilen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen,
int critical, int skip_certs)
{
@@ -705,6 +709,38 @@ int x509_authority_key_identifier_from_der(
return 1;
}
int x509_authority_key_identifier_validate(const uint8_t *a, size_t alen)
{
const uint8_t *keyid;
size_t keyid_len;
const uint8_t *issuer;
size_t issuer_len;
const uint8_t *serial;
size_t serial_len;
if (x509_authority_key_identifier_from_der(
&keyid, &keyid_len,
&issuer, &issuer_len,
&serial, &serial_len, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
if (!keyid && !issuer && !serial) {
error_print();
return -1;
}
if (issuer) {
/*
if (asn1_general_names_validate(issuer, issuer_len) != 1) {
error_print();
return -1;
}
*/
}
return 1;
}
int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int ret;
@@ -1118,6 +1154,12 @@ int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, s
return -1;
}
int x509_certificate_polices_validate(const uint8_t *d, size_t dlen)
{
error_print();
return -1;
}
int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *p;
@@ -1201,6 +1243,16 @@ err:
return -1;
}
int x509_policy_mapping_validate(const uint8_t *a, size_t alen)
{
return -1;
}
int x509_policy_mappings_validate(const uint8_t *d, size_t dlen)
{
return -1;
}
int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *p;
@@ -1343,6 +1395,8 @@ int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t *
return 1;
}
// 这个函数原型可能要改一下
int x509_basic_constraints_validate(int ca, int path_len_cons, int cert_type)
{
/*
@@ -1598,6 +1652,12 @@ int x509_policy_constraints_from_der(
return 1;
}
int x509_policy_constraints_validate(const uint8_t *a, size_t alen)
{
return -1;
}
int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int ret, val;
@@ -1670,6 +1730,7 @@ int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, con
return 1;
}
// 这个函数原型可能也要改一下
int x509_ext_key_usage_validate(const int *oids, size_t oids_cnt, int cert_type)
{
int ret = -1;
@@ -1994,6 +2055,11 @@ err:
return -1;
}
int x509_distribution_points_validate(const uint8_t *d, size_t dlen)
{
return -1;
}
int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *p;
@@ -2055,6 +2121,69 @@ int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
}
switch (oid) {
case OID_ce_authority_key_identifier:
if (critical == X509_critical) {
error_print();
return -1;
}
/*
if (x509_authority_key_identifier(val, vlen) != 1) {
error_print();
return -1;
}
*/
break;
case OID_ce_subject_key_identifier:
if (critical == X509_critical) {
error_print();
return -1;
}
const uint8_t *p;
size_t len;
if (asn1_octet_string_from_der(&p, &len, &val, &vlen) != 1
|| asn1_length_is_zero(vlen) != 1) {
error_print();
return -1;
}
if (!p || !len) {
error_print();
return -1;
}
break;
case OID_ce_key_usage:
if (critical != X509_critical) {
error_print();
// conforming CAs SHOULD mark this extension as critical.
}
if (asn1_bits_from_der(&key_usage, &val, &vlen) != 1
|| x509_key_usage_validate(key_usage, cert_type) != 1) {
error_print();
return -1;
}
break;
case OID_ce_certificate_policies:
break;
case OID_ce_policy_mappings:
if (critical != X509_critical) {
error_print();
return -1;
}
break;
case OID_ce_subject_alt_name:
break;
case OID_ce_issuer_alt_name:
if (critical == X509_critical) {
error_print();
return -1;
}
break;
case OID_ce_subject_directory_attributes:
if (critical == X509_critical) {
error_print();
return -1;
}
break;
case OID_ce_basic_constraints:
if (x509_basic_constraints_from_der(&ca, &path_len, &val, &vlen) != 1
|| x509_basic_constraints_validate(ca, path_len, cert_type) != 1) {
@@ -2063,13 +2192,7 @@ int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
}
break;
case OID_ce_key_usage:
if (asn1_bits_from_der(&key_usage, &val, &vlen) != 1
|| x509_key_usage_validate(key_usage, cert_type) != 1) {
error_print();
return -1;
}
break;
case OID_ce_ext_key_usage:
if (x509_ext_key_usage_from_der(ext_key_usages, &ext_key_usages_cnt,
@@ -2080,20 +2203,15 @@ int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
}
break;
case OID_ce_authority_key_identifier:
case OID_ce_subject_key_identifier:
case OID_ce_certificate_policies:
case OID_ce_policy_mappings:
case OID_ce_subject_alt_name:
case OID_ce_issuer_alt_name:
case OID_ce_subject_directory_attributes:
case OID_ce_name_constraints:
case OID_ce_policy_constraints:
case OID_ce_crl_distribution_points:
case OID_ce_inhibit_any_policy:
case OID_ce_freshest_crl:
break;
default:
if (critical) {
if (critical == X509_critical) {
error_print();
return -1;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -12,6 +12,7 @@
#include <string.h>
#include <stdlib.h>
#include <gmssl/http.h>
#include <gmssl/x509_crl.h>
#include <gmssl/error.h>
@@ -77,17 +78,33 @@ static int test_http_parse_uri_bad(void)
return 1;
}
static int test_http_get_crl(void)
{
char *tests[] = {
"http://crl.pki.goog/gsr1/gsr1.crl",
};
uint8_t buf[65536];
size_t contentlen;
size_t i;
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
if (http_get(tests[i], buf, &contentlen, sizeof(buf)) != 1) {
fprintf(stderr, "%s() tests[%zu] <%s> failure\n", __FUNCTION__, i, tests[i]);
error_print();
return -1;
}
x509_crl_print(stderr, 0, 0, "CRL", buf, contentlen);
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
if (test_http_parse_uri() != 1) { error_print(); return -1; }
if (test_http_parse_uri_bad() != 1) { error_print(); return -1; }
if (test_http_get_crl() != 1) { error_print(); return -1; }
printf("%s all tests passed\n", __FILE__);
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
#include <gmssl/x509_alg.h>
#include <gmssl/x509_oid.h>
#include <gmssl/x509_crl.h>
#include <gmssl/x509_ext.h>
#include <gmssl/x509.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
@@ -83,34 +84,132 @@ static int test_x509_crl_entry_ext(void)
return 1;
}
static int test_x509_crl_entry_exts(void)
static int test_vector_gen_uri_as_general_names(void)
{
uint8_t exts[2560];
size_t extslen = 0;
int reason = X509_cr_key_compromise;
time_t tv;
uint8_t issuer[256];
size_t issuer_len = 0;
int critical = 1;
const char *uri = "http://www.example.com/path";
uint8_t buf[256];
uint8_t *p;
const uint8_t *cp;
size_t len;
const uint8_t *d;
size_t dlen;
size_t i;
uint8_t buf[5120];
uint8_t *p = buf;
const uint8_t *cp = buf;
size_t len = 0;
//FIXME: set issuer
issuer_len = 20;
time(&tv);
if (x509_crl_entry_exts_add_reason(exts, &extslen, sizeof(exts), critical, reason) != 1
//|| x509_crl_entry_exts_add_invalidity_date(exts, &extslen, sizeof(exts), critical, tv) != 1 //FIXME u_time related
|| x509_crl_entry_exts_add_certificate_issuer(exts, &extslen, sizeof(exts), critical, issuer, issuer_len) != 1
|| x509_crl_entry_exts_to_der(exts, extslen, &p, &len) != 1
) {
cp = p = buf; len = 0;
if (x509_uri_as_general_names_to_der(uri, strlen(uri), &p, &len) != 1
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
printf("// generated by %s()\n", __FUNCTION__);
printf("const uint8_t cert_issuer[] = {\n\t");
for (i = 0; i < dlen; i++) {
printf("0x%02x,", d[i]);
if ((i + 1) % 8 == 0) printf("\n\t");
}
printf("\n};\n");
return 1;
}
static int test_x509_crl_entry_exts(void)
{
// generated by test_vector_gen_uri_as_general_names()
const uint8_t cert_issuer[] = {
0x86,0x1b,0x68,0x74,0x74,0x70,0x3a,0x2f,
0x2f,0x77,0x77,0x77,0x2e,0x65,0x78,0x61,
0x6d,0x70,0x6c,0x65,0x2e,0x63,0x6f,0x6d,
0x2f,0x70,0x61,0x74,0x68,
};
struct {
int reason;
time_t invalid_date;
const uint8_t *cert_issuer;
size_t cert_issuer_len;
} tests[] = {
{ X509_cr_key_compromise, -1, NULL, 0 },
{ -1, time(NULL), NULL, 0 },
{ -1, -1, cert_issuer, sizeof(cert_issuer) },
{ X509_cr_key_compromise, time(NULL), NULL, 0 },
{ X509_cr_key_compromise, time(NULL), cert_issuer, sizeof(cert_issuer) },
};
uint8_t buf[1024];
uint8_t *p;
const uint8_t *cp;
size_t len;
size_t i;
int reason;
time_t invalid_date;
const uint8_t *issuer;
size_t issuer_len;
cp = p = buf; len = 0;
if (x509_crl_entry_exts_to_der(-1, -1, NULL, 0, &p, &len) != 0) {
error_print();
return -1;
}
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
if (x509_crl_entry_exts_to_der(
tests[i].reason,
tests[i].invalid_date,
tests[i].cert_issuer,
tests[i].cert_issuer_len, &p, &len) != 1) {
error_print();
return -1;
}
//printf("%s %d: test %zu passed\n", __FILE__, __LINE__, i);
if (len > sizeof(buf)) {
error_print();
return -1;
}
}
{
size_t left = len;
const uint8_t *d;
size_t dlen;
cp = buf;
while (left) {
if (asn1_sequence_from_der(&d, &dlen, &cp, &left) != 1) {
error_print();
return -1;
}
x509_crl_entry_exts_print(stderr, 0, 0, "CRLEntryExtensions", d, dlen);
if (x509_crl_entry_exts_validate(d, dlen) != 1) {
error_print();
return -1;
}
}
}
cp = p = buf;
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
if (x509_crl_entry_exts_from_der(&reason, &invalid_date, &issuer, &issuer_len, &cp, &len) != 1) {
error_print();
return -1;
}
if (reason != tests[i].reason) {
error_print();
return -1;
}
if (invalid_date != tests[i].invalid_date) {
error_print();
return -1;
}
if (issuer_len != tests[i].cert_issuer_len || memcmp(issuer, tests[i].cert_issuer, issuer_len) != 0) {
error_print();
return -1;
}
//printf("%s %d: test %zu passed\n", __FILE__, __LINE__, i);
}
if (len != 0) {
error_print();
return -1;
}
x509_crl_entry_exts_print(stderr, 0, 0, "CRLEntryExtensions", exts, extslen);
printf("%s() ok\n", __FUNCTION__);
return 1;
@@ -118,19 +217,32 @@ static int test_x509_crl_entry_exts(void)
static int test_x509_revoked_cert(void)
{
uint8_t serial[20] = { 0x01,0x02 };
time_t revoke_date;
uint8_t serial_buf[16] = { 0x01,0x02,0x00 };
time_t revoke_date = time(NULL);
int reason = X509_cr_key_compromise;
time_t invalid_date = revoke_date;
// generated by test_vector_gen_uri_as_general_names()
const uint8_t cert_issuer_buf[] = {
0x86,0x1b,0x68,0x74,0x74,0x70,0x3a,0x2f,
0x2f,0x77,0x77,0x77,0x2e,0x65,0x78,0x61,
0x6d,0x70,0x6c,0x65,0x2e,0x63,0x6f,0x6d,
0x2f,0x70,0x61,0x74,0x68,
};
const uint8_t *serial;
size_t serial_len;
const uint8_t *cert_issuer;
size_t cert_issuer_len;
uint8_t buf[512];
uint8_t *p = buf;
const uint8_t *cp = buf;
uint8_t *p;
const uint8_t *cp;
size_t len = 0;
const uint8_t *d;
size_t dlen;
time(&revoke_date);
if (x509_revoked_cert_to_der(serial, sizeof(serial), revoke_date, NULL, 0, &p, &len) != 1
cp = p = buf; len = 0;
if (x509_revoked_cert_to_der_ex(serial_buf, sizeof(serial_buf), revoke_date,
reason, invalid_date, cert_issuer_buf, sizeof(cert_issuer_buf), &p, &len) != 1
|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
@@ -138,9 +250,100 @@ static int test_x509_revoked_cert(void)
}
x509_revoked_cert_print(stderr, 0, 0, "RevokedCertificate", d, dlen);
cp = p = buf; len = 0;
if (x509_revoked_cert_to_der_ex(serial_buf, sizeof(serial_buf), revoke_date,
reason, invalid_date, cert_issuer_buf, sizeof(cert_issuer_buf), &p, &len) != 1
|| x509_revoked_cert_from_der_ex(&serial, &serial_len, &revoke_date,
&reason, &invalid_date, &cert_issuer, &cert_issuer_len, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_x509_crl_ext_id(void)
{
int crl_ext_oids[] = {
OID_ce_authority_key_identifier,
OID_ce_issuer_alt_name,
OID_ce_crl_number,
OID_ce_delta_crl_indicator,
OID_ce_issuing_distribution_point,
OID_ce_freshest_crl,
OID_pe_authority_info_access,
};
int oid;
uint8_t buf[512];
uint8_t *p;
const uint8_t *cp;
size_t len;
size_t i;
cp = p = buf; len = 0;
for (i = 0; i < sizeof(crl_ext_oids)/sizeof(crl_ext_oids[0]); i++) {
if (x509_crl_ext_id_to_der(crl_ext_oids[i], &p, &len) != 1) {
error_print();
return -1;
}
format_bytes(stderr, 0, 0, "", buf, len);
}
for (i = 0; i < sizeof(crl_ext_oids)/sizeof(crl_ext_oids[0]); i++) {
if (x509_crl_ext_id_from_der(&oid, &cp, &len) != 1) {
error_print();
return -1;
}
printf(" %s\n", x509_crl_ext_id_name(oid));
}
if (len) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_x509_crl_exts(void)
{
/*
uint8_t exts[1024];
size_t extslen = 0;
if (0
|| x509_crl_exts_add_authority_key_identifier(exts, &extslen, sizeof(exts),
X509_non_critical, key_id, sizeof(key_id), issuer, sizeof(issuer), serial, sizeof(serial)) != 1
|| x509_crl_exts_add_issuer_alt_name(exts, &extslen, sizeof(exts),
X509_non_critical, issuer_alt_name, sizeof(issuer_alt_name)) != 1
|| x509_crl_exts_add_crl_number(exts, &extslen, sizeof(exts),
X509_non_critical, 112) != 1
|| x509_crl_exts_add_delta_crl_indicator(exts, &extslen, sizeof(exts),
X509_non_critical, 113) != 1
|| x509_crl_exts_add_issuing_distribution_point(exts, &extslen, sizeof(exts),
X509_non_critical, dist_point_uri, strlen(dist_point_uri),
ASN1_FALSE, ASN1_FALSE, -1, ASN1_FALSE, ASN1_FALSE) != 1
|| x509_crl_exts_add_freshest_crl(exts, &extslen, sizeof(exts),
X509_non_critical, http_uri, strlen(http_uri), ldap_uri, strlen(ldap_uri)) != 1
|| x509_crl_exts_add_authority_info_acess(exts, &extslen, sizeof(exts),
X509_non_critical, ca_issuers_uri, strlen(ca_issuers_uri), ocsp_uri, strlen(ocsp_uri)) != 1) {
error_print();
return -1;
}
x509_crl_exts_print(stderr, 0, 0, "CRLExtensions", exts, extslen);
*/
return 1;
}
static int test_x509_cert_revoke(void)
{
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
@@ -148,6 +351,8 @@ int main(void)
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;
// if (test_vector_gen_uri_as_general_names() != 1) goto err;
if (test_x509_crl_ext_id() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:

139
tools/certrevoke.c Normal file
View File

@@ -0,0 +1,139 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/pem.h>
#include <gmssl/x509.h>
#include <gmssl/x509_crl.h>
// 20220105Z
static const char *options = "-in cert.pem [-reason str] [-invalid_date timestamp] [-out RevokedCertificate.der]";
static void print_options(FILE *fp, const char *prog)
{
int i;
fprintf(fp, "Options:\n");
fprintf(fp, " -in cert.pem Certificate in PEM format to be revoked\n");
fprintf(fp, " -reason code Revocation reason code, avaiable codes:\n");
for (i = 0; i <= X509_cr_aa_compromise; i++) {
fprintf(fp, " %s (%d)\n", x509_crl_reason_name(i), i);
}
fprintf(fp, " -invalid_date time Revocation timestamp in YYYYMMDDHHMMSSZ format\n");
fprintf(fp, " Example: -invalid_date 20221231000000Z\n");
fprintf(fp, " -out file.der Output ASN.1 RevokedCertificate in DER format\n");
fprintf(fp, "Examples:\n");
fprintf(fp, " %s -in cert1.pem -reason keyCompromise -invalid_date 20221230000000Z -out revoked_certs.der\n", prog);
fprintf(fp, " %s -in cert2.pem -reason keyCompromise -invalid_date 20221231000000Z >> revoked_certs.der\n", prog);
}
int certrevoke_main(int argc, char **argv)
{
int ret = 1;
char *prog = argv[0];
char *infile = NULL;
char *outfile = NULL;
int reason = -1;
time_t invalid_date = -1;
uint8_t *cert = NULL;
size_t certlen;
uint8_t *outbuf = NULL;
uint8_t *out;
size_t outlen;
FILE *outfp = stdout;
argc--;
argv++;
while (argc > 0) {
if (!strcmp(*argv, "-help")) {
printf("usage: %s %s\n", prog, options);
print_options(stdout, prog);
goto end;
} else if (!strcmp(*argv, "-in")) {
if (--argc < 1) goto bad;
infile = *(++argv);
if (x509_cert_new_from_file(&cert, &certlen, infile) != 1) {
fprintf(stderr, "%s: open cert file %s failure\n", prog, infile);
goto end;
}
} else if (!strcmp(*argv, "-out")) {
if (--argc < 1) goto bad;
outfile = *(++argv);
if (!(outfp = fopen(outfile, "wb"))) {
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
goto end;
}
} else if (!strcmp(*argv, "-reason")) {
char *name;
int i;
if (--argc < 1) goto bad;
name = *(++argv);
if (x509_crl_reason_from_name(&reason, name) != 1) {
fprintf(stderr, "%s: invalid reason '%s'\n", prog, name);
fprintf(stderr, "-reason values:\n");
for (i = 0; i <= X509_cr_aa_compromise; i++) {
fprintf(stderr, " %s\n", x509_crl_reason_name(i));
}
}
} else if (!strcmp(*argv, "-invalid_date")) {
char *time_str;
if (--argc < 1) goto bad;
time_str =*(++argv);
if (asn1_time_from_str(0, &invalid_date, time_str) != 1) {
fprintf(stderr, "%s: invalid time '%s', should provide 'YYYYMMDDHHMMSSZ'\n", prog, time_str);
goto bad;
}
} else {
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
goto end;
bad:
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
goto end;
}
argc--;
argv++;
}
if (!infile) {
fprintf(stderr, "usage: %s %s\n", prog, options);
goto end;
}
if (x509_cert_revoke_to_der(cert, certlen, time(NULL), reason, invalid_date, NULL, 0, NULL, &outlen) != 1) {
fprintf(stderr, "%s: inner error\n", prog);
goto end;
}
if (!(outbuf = malloc(outlen))) {
fprintf(stderr, "%s: malloc failure\n", prog);
goto end;
}
out = outbuf;
outlen = 0;
if (x509_cert_revoke_to_der(cert, certlen, time(NULL), reason, invalid_date, NULL, 0, &out, &outlen) != 1) {
fprintf(stderr, "%s: inner error\n", prog);
goto end;
}
if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
fprintf(stderr, "%s: output failure\n", prog);
goto end;
}
ret = 0;
end:
if (cert) free(cert);
if (outfile && outfp) fclose(outfp);
if (outbuf) free(outbuf);
return ret;
}

161
tools/crlgen.c Normal file
View File

@@ -0,0 +1,161 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/pem.h>
#include <gmssl/x509.h>
#include <gmssl/x509_crl.h>
#include <gmssl/file.h>
static const char *options =
"-in RevokedCertificate.der"
" -key pem -pass str -cert pem"
" [-next_update timestamp] "
" [-out crl.der]";
int crlgen_main(int argc, char **argv)
{
int ret = 1;
char *prog = argv[0];
char *infile = NULL;
uint8_t *revoked_certs = NULL;
size_t revoked_certs_len = 0;
char *outfile = NULL;
FILE *outfp = stdout;
char *keyfile = NULL;
char *pass = NULL;
FILE *keyfp = NULL;
SM2_KEY sign_key;
char *cacertfile = NULL;
uint8_t *cacert = NULL;
size_t cacert_len = 0;
const uint8_t *issuer;
size_t issuer_len;
time_t next_update = -1;
uint8_t outbuf[64 * 1024];
uint8_t *out = outbuf;
size_t outlen = 0;
argc--;
argv++;
while (argc > 0) {
if (!strcmp(*argv, "-help")) {
printf("usage: %s %s\n", prog, options);
goto end;
} else if (!strcmp(*argv, "-in")) {
if (--argc < 1) goto bad;
infile = *(++argv);
if (file_read_all(infile, &revoked_certs, &revoked_certs_len) != 1) {
fprintf(stderr, "%s: read input file failed\n", prog);
goto end;
}
} else if (!strcmp(*argv, "-out")) {
if (--argc < 1) goto bad;
outfile = *(++argv);
if (!(outfp = fopen(outfile, "wb"))) {
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
goto end;
}
} else if (!strcmp(*argv, "-key")) {
if (--argc < 1) goto bad;
keyfile = *(++argv);
if (!(keyfp = fopen(keyfile, "rb"))) {
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno));
goto end;
}
} else if (!strcmp(*argv, "-pass")) {
if (--argc < 1) goto bad;
} else if (!strcmp(*argv, "-cacert")) {
if (--argc < 1) goto bad;
cacertfile = *(++argv);
if (x509_cert_new_from_file(&cacert, &cacert_len, cacertfile) != 1) {
goto end;
}
} else if (!strcmp(*argv, "-next_update")) {
if (--argc < 1) goto bad;
next_update = atoi(*(++argv));
} else {
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
goto end;
bad:
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
goto end;
}
argc--;
argv++;
}
if (!infile) {
fprintf(stderr, "%s: '-in' option required\n", prog);
goto end;
}
if (!cacertfile) {
fprintf(stderr, "%s: '-cacert' option required\n", prog);
goto end;
}
if (!keyfile) {
fprintf(stderr, "%s: '-key' option required\n", prog);
goto end;
}
if (!pass) {
fprintf(stderr, "%s: '-pass' option required\n", prog);
goto end;
}
if (!revoked_certs || !revoked_certs_len) {
fprintf(stderr, "usage: %s %s\n", prog, options);
goto end;
}
if (x509_cert_get_subject(cacert, cacert_len, &issuer, &issuer_len) != 1) {
fprintf(stderr, "%s: parse CA certificate failure\n", prog);
goto end;
}
if (sm2_private_key_info_decrypt_from_pem(&sign_key, pass, keyfp) != 1) {
fprintf(stderr, "%s: load private key failure\n", prog);
goto end;
}
if (x509_crl_sign_to_der(
X509_version_v2,
OID_sm2sign_with_sm3,
issuer, issuer_len,
time(NULL), next_update,
revoked_certs, revoked_certs_len,
NULL, 0,
&sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH,
&out, &outlen) != 1) {
// error_print();
return -1;
}
if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
fprintf(stderr, "%s: output failure\n", prog);
return -1;
}
ret = 0;
end:
//if (cert) free(cert);
if (outfile && outfp) fclose(outfp);
return ret;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@@ -18,6 +18,8 @@ extern int rand_main(int argc, char **argv);
extern int certgen_main(int argc, char **argv);
extern int certparse_main(int argc, char **argv);
extern int certverify_main(int argc, char **argv);
extern int certrevoke_main(int argc, char **argv);
extern int crlgen_main(int argc, char **argv);
extern int crlparse_main(int argc, char **argv);
extern int crlverify_main(int argc, char **argv);
extern int pbkdf2_main(int argc, char **argv);
@@ -80,11 +82,13 @@ static const char *options =
" reqgen Generate certificate signing request (CSR)\n"
" reqsign Generate certificate from CSR\n"
" reqparse Parse and print a CSR\n"
" crlgen Sign a CRL with CA certificate and private key\n"
" crlparse Verify a CRL with certificate\n"
" crlverify Parse and print CRL\n"
" certgen Generate a self-signed certificate\n"
" certparse Parse and print certificates\n"
" certverify Verify certificate chain\n"
" certrevoke Revoke certificate and output RevokedCertificate in DER\n"
" cmsparse Parse cryptographic message syntax (CMS)\n"
" cmsencrypt Generate CMS EnvelopedData\n"
" cmsdecrypt Decrypt CMS EnvelopedData\n"
@@ -128,6 +132,10 @@ int main(int argc, char **argv)
return certparse_main(argc, argv);
} else if (!strcmp(*argv, "certverify")) {
return certverify_main(argc, argv);
} else if (!strcmp(*argv, "certrevoke")) {
return certrevoke_main(argc, argv);
} else if (!strcmp(*argv, "crlgen")) {
return crlgen_main(argc, argv);
} else if (!strcmp(*argv, "crlparse")) {
return crlparse_main(argc, argv);
} else if (!strcmp(*argv, "crlverify")) {