mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-19 11:23:38 +08:00
Update OCSP
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/x509.h>
|
||||
@@ -26,6 +27,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CertID ::= SEQUENCE {
|
||||
hashAlgorithm AlgorithmIdentifier,
|
||||
@@ -87,12 +90,61 @@ int ocsp_request_generate(uint8_t *req, size_t *reqlen, size_t maxlen,
|
||||
const uint8_t *issuer_cert, size_t issuer_certlen,
|
||||
const DIGEST *digest);
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
SingleResponse ::= SEQUENCE {
|
||||
certID CertID,
|
||||
certStatus CertStatus,
|
||||
thisUpdate GeneralizedTime,
|
||||
nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
|
||||
singleExtensions [1] EXPLICIT Extensions OPTIONAL }
|
||||
|
||||
CertStatus ::= CHOICE {
|
||||
good [0] IMPLICIT NULL,
|
||||
revoked [1] IMPLICIT RevokedInfo,
|
||||
unknown [2] IMPLICIT UnknownInfo }
|
||||
|
||||
RevokedInfo ::= SEQUENCE {
|
||||
revocationTime GeneralizedTime,
|
||||
revocationReason [0] EXPLICIT CRLReason OPTIONAL }
|
||||
|
||||
UnknownInfo ::= NULL
|
||||
*/
|
||||
enum {
|
||||
OCSP_cert_status_good,
|
||||
OCSP_cert_status_revoked,
|
||||
OCSP_cert_status_unknown,
|
||||
};
|
||||
|
||||
int ocsp_single_response_to_der(int hash_algor,
|
||||
const uint8_t *issuer_name_hash, size_t issuer_name_hash_len,
|
||||
const uint8_t *issuer_key_hash, size_t issuer_key_hash_len,
|
||||
const uint8_t *serial_number, size_t serial_number_len,
|
||||
int cert_status, time_t revocation_time, int revocation_reason,
|
||||
time_t this_update, time_t next_update,
|
||||
const uint8_t *exts, size_t extslen,
|
||||
uint8_t **out, size_t *outlen);
|
||||
int ocsp_single_response_from_der(int *hash_algor,
|
||||
const uint8_t **issuer_name_hash, size_t *issuer_name_hash_len,
|
||||
const uint8_t **issuer_key_hash, size_t *issuer_key_hash_len,
|
||||
const uint8_t **serial_number, size_t *serial_number_len,
|
||||
int *cert_status, time_t *revocation_time, int *revocation_reason,
|
||||
time_t *this_update, time_t *next_update,
|
||||
const uint8_t **exts, size_t *extslen,
|
||||
const uint8_t **in, size_t *inlen);
|
||||
int ocsp_single_response_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
const uint8_t *d, size_t dlen);
|
||||
|
||||
|
||||
/*
|
||||
OCSPResponse ::= SEQUENCE {
|
||||
responseStatus OCSPResponseStatus,
|
||||
responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
OCSPResponseStatus ::= ENUMERATED {
|
||||
successful (0),
|
||||
malformedRequest (1),
|
||||
@@ -100,7 +152,25 @@ OCSPResponseStatus ::= ENUMERATED {
|
||||
tryLater (3),
|
||||
sigRequired (5),
|
||||
unauthorized (6) }
|
||||
*/
|
||||
enum {
|
||||
OCSP_response_status_successful = 0,
|
||||
OCSP_response_status_malformed_request = 1,
|
||||
OCSP_response_status_internal_error = 2,
|
||||
OCSP_response_status_try_later = 3,
|
||||
OCSP_response_status_sig_required = 5,
|
||||
OCSP_response_status_unauthorized = 6,
|
||||
};
|
||||
|
||||
|
||||
#define OCSP_responder_id_by_name 1
|
||||
#define OCSP_responder_id_by_key 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
ResponseBytes ::= SEQUENCE {
|
||||
responseType OBJECT IDENTIFIER,
|
||||
response OCTET STRING }
|
||||
@@ -125,46 +195,49 @@ ResponderID ::= CHOICE {
|
||||
byKey [2] KeyHash }
|
||||
|
||||
KeyHash ::= OCTET STRING
|
||||
*/
|
||||
|
||||
SingleResponse ::= SEQUENCE {
|
||||
certID CertID,
|
||||
certStatus CertStatus,
|
||||
thisUpdate GeneralizedTime,
|
||||
nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
|
||||
singleExtensions [1] EXPLICIT Extensions OPTIONAL }
|
||||
|
||||
CertStatus ::= CHOICE {
|
||||
good [0] IMPLICIT NULL,
|
||||
revoked [1] IMPLICIT RevokedInfo,
|
||||
unknown [2] IMPLICIT UnknownInfo }
|
||||
|
||||
RevokedInfo ::= SEQUENCE {
|
||||
revocationTime GeneralizedTime,
|
||||
revocationReason [0] EXPLICIT CRLReason OPTIONAL }
|
||||
|
||||
UnknownInfo ::= NULL
|
||||
|
||||
ArchiveCutoff ::= GeneralizedTime
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER
|
||||
|
||||
ServiceLocator ::= SEQUENCE {
|
||||
issuer Name,
|
||||
locator AuthorityInfoAccessSyntax OPTIONAL }
|
||||
|
||||
CrlID ::= SEQUENCE {
|
||||
crlUrl [0] EXPLICIT IA5String OPTIONAL,
|
||||
crlNum [1] EXPLICIT INTEGER OPTIONAL,
|
||||
crlTime [2] EXPLICIT GeneralizedTime OPTIONAL }
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
PreferredSignatureAlgorithms ::= SEQUENCE OF PreferredSignatureAlgorithm
|
||||
|
||||
PreferredSignatureAlgorithm ::= SEQUENCE {
|
||||
sigIdentifier AlgorithmIdentifier,
|
||||
certIdentifier AlgorithmIdentifier OPTIONAL }
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -104,6 +104,10 @@ enum {
|
||||
OID_ce_invalidity_date,
|
||||
OID_ce_certificate_issuer,
|
||||
|
||||
// OCSP
|
||||
OID_pkix_ocsp_crl,
|
||||
OID_pkix_ocsp_archive_cutoff,
|
||||
|
||||
// X.509 KeyPropuseID
|
||||
OID_any_extended_key_usage,
|
||||
OID_kp_server_auth,
|
||||
@@ -219,7 +223,6 @@ enum {
|
||||
#define oid_cnt(nodes) (sizeof(nodes)/sizeof((nodes)[0]))
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
737
src/ocsp.c
737
src/ocsp.c
@@ -15,9 +15,26 @@
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/x509_crl.h>
|
||||
#include <gmssl/ocsp.h>
|
||||
|
||||
|
||||
static const char *ocsp_cert_status_name(int status)
|
||||
{
|
||||
switch (status) {
|
||||
case OCSP_cert_status_good:
|
||||
return "good";
|
||||
case OCSP_cert_status_revoked:
|
||||
return "revoked";
|
||||
case OCSP_cert_status_unknown:
|
||||
return "unknown";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ocsp_request_item_to_der(int hash_algor,
|
||||
const uint8_t *issuer_name_hash, size_t issuer_name_hash_len,
|
||||
const uint8_t *issuer_key_hash, size_t issuer_key_hash_len,
|
||||
@@ -108,26 +125,38 @@ int ocsp_request_item_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_sequence_from_der(&seq, &seq_len, &d, &dlen) != 1) goto err;
|
||||
if (asn1_sequence_from_der(&seq, &seq_len, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "reqCert\n");
|
||||
if (asn1_sequence_from_der(&cert_id, &cert_id_len, &seq, &seq_len) != 1) goto err;
|
||||
if (x509_digest_algor_from_der(&hash_algor, &cert_id, &cert_id_len) != 1) goto err;
|
||||
if (asn1_octet_string_from_der(&issuer_name_hash, &issuer_name_hash_len, &cert_id, &cert_id_len) != 1) goto err;
|
||||
if (asn1_octet_string_from_der(&issuer_key_hash, &issuer_key_hash_len, &cert_id, &cert_id_len) != 1) goto err;
|
||||
if (asn1_integer_from_der(&serial, &serial_len, &cert_id, &cert_id_len) != 1) goto err;
|
||||
if (asn1_sequence_from_der(&cert_id, &cert_id_len, &seq, &seq_len) != 1
|
||||
|| x509_digest_algor_from_der(&hash_algor, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_octet_string_from_der(&issuer_name_hash, &issuer_name_hash_len, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_octet_string_from_der(&issuer_key_hash, &issuer_key_hash_len, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_integer_from_der(&serial, &serial_len, &cert_id, &cert_id_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind + 4, "hashAlgorithm: %s\n", x509_digest_algor_name(hash_algor));
|
||||
format_bytes(fp, fmt, ind + 4, "issuerNameHash", issuer_name_hash, issuer_name_hash_len);
|
||||
format_bytes(fp, fmt, ind + 4, "issuerKeyHash", issuer_key_hash, issuer_key_hash_len);
|
||||
format_bytes(fp, fmt, ind + 4, "serialNumber", serial, serial_len);
|
||||
if (asn1_length_is_zero(cert_id_len) != 1) goto err;
|
||||
if (x509_explicit_exts_from_der(0, &p, &len, &seq, &seq_len) < 0) goto err;
|
||||
if (p) x509_exts_print(fp, fmt, ind, "singleRequestExtensions", p, len);
|
||||
if (asn1_length_is_zero(seq_len) != 1) goto err;
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
if (asn1_length_is_zero(cert_id_len) != 1
|
||||
|| x509_explicit_exts_from_der(0, &p, &len, &seq, &seq_len) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p && x509_exts_print(fp, fmt, ind, "singleRequestExtensions", p, len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_length_is_zero(seq_len) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ocsp_request_to_der(int version,
|
||||
@@ -223,36 +252,66 @@ int ocsp_request_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_sequence_from_der(&seq, &seq_len, &d, &dlen) != 1) goto err;
|
||||
if (asn1_sequence_from_der(&tbs_request, &tbs_request_len, &seq, &seq_len) != 1) goto err;
|
||||
if (asn1_sequence_from_der(&seq, &seq_len, &d, &dlen) != 1
|
||||
|| asn1_sequence_from_der(&tbs_request, &tbs_request_len, &seq, &seq_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "tbsRequest\n");
|
||||
ind += 4;
|
||||
if ((ret = x509_explicit_version_from_der(0, &version, &tbs_request, &tbs_request_len)) < 0) goto err;
|
||||
if ((ret = x509_explicit_version_from_der(0, &version, &tbs_request, &tbs_request_len)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (version == -1) version = X509_version_v1;
|
||||
if (ret) format_print(fp, fmt, ind, "version: v1 (%d)\n", version);
|
||||
if (version != X509_version_v1) goto err;
|
||||
if ((ret = asn1_explicit_from_der(1, &p, &len, &tbs_request, &tbs_request_len)) < 0) goto err;
|
||||
if (version != X509_version_v1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((ret = asn1_explicit_from_der(1, &p, &len, &tbs_request, &tbs_request_len)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (ret) format_bytes(fp, fmt, ind, "requestorName", p, len);
|
||||
if (asn1_sequence_from_der(&request_list, &request_list_len, &tbs_request, &tbs_request_len) != 1) goto err;
|
||||
if (asn1_sequence_from_der(&request_list, &request_list_len, &tbs_request, &tbs_request_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "requestList\n");
|
||||
while (request_list_len) {
|
||||
const uint8_t *request;
|
||||
size_t request_len;
|
||||
if (asn1_any_from_der(&request, &request_len, &request_list, &request_list_len) != 1) goto err;
|
||||
if (ocsp_request_item_print(fp, fmt, ind + 4, "Request", request, request_len) != 1) goto err;
|
||||
if (asn1_any_from_der(&request, &request_len, &request_list, &request_list_len) != 1
|
||||
|| ocsp_request_item_print(fp, fmt, ind + 4, "Request", request, request_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (x509_explicit_exts_from_der(2, &p, &len, &tbs_request, &tbs_request_len) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p && x509_exts_print(fp, fmt, ind, "requestExtensions", p, len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_length_is_zero(tbs_request_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_explicit_exts_from_der(2, &p, &len, &tbs_request, &tbs_request_len) < 0) goto err;
|
||||
if (p) x509_exts_print(fp, fmt, ind, "requestExtensions", p, len);
|
||||
if (asn1_length_is_zero(tbs_request_len) != 1) goto err;
|
||||
ind -= 4;
|
||||
if (asn1_explicit_from_der(0, &p, &len, &seq, &seq_len) < 0) goto err;
|
||||
if (asn1_explicit_from_der(0, &p, &len, &seq, &seq_len) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) format_bytes(fp, fmt, ind, "optionalSignature", p, len);
|
||||
if (asn1_length_is_zero(seq_len) != 1) goto err;
|
||||
if (asn1_length_is_zero(dlen) != 1) goto err;
|
||||
if (asn1_length_is_zero(seq_len) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ocsp_request_generate(uint8_t *req, size_t *reqlen, size_t maxlen,
|
||||
@@ -337,3 +396,619 @@ int ocsp_request_generate(uint8_t *req, size_t *reqlen, size_t maxlen,
|
||||
*reqlen = outlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
CrlID ::= SEQUENCE {
|
||||
crlUrl [0] EXPLICIT IA5String OPTIONAL,
|
||||
crlNum [1] EXPLICIT INTEGER OPTIONAL,
|
||||
crlTime [2] EXPLICIT GeneralizedTime OPTIONAL }
|
||||
*/
|
||||
static int ocsp_crl_id_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
const char *crl_url;
|
||||
size_t crl_url_len;
|
||||
const uint8_t *crl_num;
|
||||
size_t crl_num_len;
|
||||
time_t crl_time;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (!d) {
|
||||
if (dlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (asn1_explicit_from_der(0, &p, &len, &d, &dlen) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
if (asn1_ia5_string_from_der(&crl_url, &crl_url_len, &p, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "crlUrl: %.*s\n", (int)crl_url_len, crl_url);
|
||||
}
|
||||
if (asn1_explicit_from_der(1, &p, &len, &d, &dlen) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
if (asn1_integer_from_der(&crl_num, &crl_num_len, &p, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_bytes(fp, fmt, ind, "crlNum", crl_num, crl_num_len);
|
||||
}
|
||||
if (asn1_explicit_from_der(2, &p, &len, &d, &dlen) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
if (asn1_generalized_time_from_der(&crl_time, &p, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "crlTime: %s", ctime(&crl_time));
|
||||
}
|
||||
if (asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
ArchiveCutoff ::= GeneralizedTime
|
||||
*/
|
||||
static int ocsp_archive_cutoff_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
const uint8_t *d, size_t dlen)
|
||||
{
|
||||
time_t archive_cutoff;
|
||||
|
||||
if (asn1_generalized_time_from_der(&archive_cutoff, &d, &dlen) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "%s: %s", label, ctime(&archive_cutoff));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ocsp_single_response_to_der(int hash_algor,
|
||||
const uint8_t *issuer_name_hash, size_t issuer_name_hash_len,
|
||||
const uint8_t *issuer_key_hash, size_t issuer_key_hash_len,
|
||||
const uint8_t *serial_number, size_t serial_number_len,
|
||||
int cert_status, time_t revocation_time, int revocation_reason,
|
||||
time_t this_update, time_t next_update,
|
||||
const uint8_t *exts, size_t extslen,
|
||||
uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t cert_id_len = 0;
|
||||
size_t revoked_info_len = 0;
|
||||
size_t revocation_reason_len = 0;
|
||||
size_t next_update_len = 0;
|
||||
size_t len = 0;
|
||||
|
||||
if (!issuer_name_hash || !issuer_name_hash_len
|
||||
|| !issuer_key_hash || !issuer_key_hash_len
|
||||
|| !serial_number || !serial_number_len
|
||||
|| !ocsp_cert_status_name(cert_status)
|
||||
|| this_update == (time_t)-1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (cert_status == OCSP_cert_status_revoked) {
|
||||
if (revocation_time == (time_t)-1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
} else if (revocation_time != (time_t)-1 || revocation_reason != -1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (x509_digest_algor_to_der(hash_algor, NULL, &cert_id_len) != 1
|
||||
|| asn1_octet_string_to_der(issuer_name_hash, issuer_name_hash_len, NULL, &cert_id_len) != 1
|
||||
|| asn1_octet_string_to_der(issuer_key_hash, issuer_key_hash_len, NULL, &cert_id_len) != 1
|
||||
|| asn1_integer_to_der(serial_number, serial_number_len, NULL, &cert_id_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (cert_status == OCSP_cert_status_revoked) {
|
||||
if (asn1_generalized_time_to_der(revocation_time, NULL, &revoked_info_len) != 1
|
||||
|| (revocation_reason >= 0
|
||||
&& x509_crl_reason_to_der(revocation_reason, NULL, &revocation_reason_len) != 1)) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (revocation_reason >= 0) {
|
||||
revoked_info_len += revocation_reason_len;
|
||||
if (asn1_explicit_header_to_der(0, revocation_reason_len, NULL, &revoked_info_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (next_update != (time_t)-1) {
|
||||
if (asn1_generalized_time_to_der(next_update, NULL, &next_update_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
len = cert_id_len;
|
||||
if (asn1_sequence_header_to_der(cert_id_len, NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
switch (cert_status) {
|
||||
case OCSP_cert_status_good:
|
||||
if (asn1_header_to_der(ASN1_TAG_IMPLICIT(0), 0, NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OCSP_cert_status_revoked:
|
||||
len += revoked_info_len;
|
||||
if (asn1_header_to_der(ASN1_TAG_EXPLICIT(1), revoked_info_len, NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OCSP_cert_status_unknown:
|
||||
if (asn1_header_to_der(ASN1_TAG_IMPLICIT(2), 0, NULL, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (asn1_generalized_time_to_der(this_update, NULL, &len) != 1
|
||||
|| (next_update != (time_t)-1 && asn1_explicit_header_to_der(0, next_update_len, NULL, &len) != 1)) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (next_update != (time_t)-1) {
|
||||
len += next_update_len;
|
||||
}
|
||||
if (x509_explicit_exts_to_der(1, exts, extslen, NULL, &len) < 0
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_sequence_header_to_der(cert_id_len, out, outlen) != 1
|
||||
|| x509_digest_algor_to_der(hash_algor, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(issuer_name_hash, issuer_name_hash_len, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(issuer_key_hash, issuer_key_hash_len, out, outlen) != 1
|
||||
|| asn1_integer_to_der(serial_number, serial_number_len, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
switch (cert_status) {
|
||||
case OCSP_cert_status_good:
|
||||
if (asn1_header_to_der(ASN1_TAG_IMPLICIT(0), 0, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OCSP_cert_status_revoked:
|
||||
if (asn1_header_to_der(ASN1_TAG_EXPLICIT(1), revoked_info_len, out, outlen) != 1
|
||||
|| asn1_generalized_time_to_der(revocation_time, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (revocation_reason >= 0) {
|
||||
size_t reason_len = 0;
|
||||
if (x509_crl_reason_to_der(revocation_reason, NULL, &reason_len) != 1
|
||||
|| asn1_explicit_header_to_der(0, reason_len, out, outlen) != 1
|
||||
|| x509_crl_reason_to_der(revocation_reason, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OCSP_cert_status_unknown:
|
||||
if (asn1_header_to_der(ASN1_TAG_IMPLICIT(2), 0, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (asn1_generalized_time_to_der(this_update, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (next_update != (time_t)-1) {
|
||||
if (asn1_explicit_header_to_der(0, next_update_len, out, outlen) != 1
|
||||
|| asn1_generalized_time_to_der(next_update, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (x509_explicit_exts_to_der(1, exts, extslen, out, outlen) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ocsp_single_response_from_der(int *hash_algor,
|
||||
const uint8_t **issuer_name_hash, size_t *issuer_name_hash_len,
|
||||
const uint8_t **issuer_key_hash, size_t *issuer_key_hash_len,
|
||||
const uint8_t **serial_number, size_t *serial_number_len,
|
||||
int *cert_status, time_t *revocation_time, int *revocation_reason,
|
||||
time_t *this_update, time_t *next_update,
|
||||
const uint8_t **exts, size_t *extslen,
|
||||
const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
int tag;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
const uint8_t *cert_id;
|
||||
size_t cert_id_len;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
const uint8_t *q;
|
||||
size_t qlen;
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
if (asn1_sequence_from_der(&cert_id, &cert_id_len, &d, &dlen) != 1
|
||||
|| x509_digest_algor_from_der(hash_algor, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_octet_string_from_der(issuer_name_hash, issuer_name_hash_len, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_octet_string_from_der(issuer_key_hash, issuer_key_hash_len, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_integer_from_der(serial_number, serial_number_len, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_length_is_zero(cert_id_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*revocation_time = (time_t)-1;
|
||||
*revocation_reason = -1;
|
||||
if (asn1_tag_from_der_readonly(&tag, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_TAG_IMPLICIT(0):
|
||||
if (asn1_implicit_from_der(0, &p, &len, &d, &dlen) != 1
|
||||
|| len != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cert_status = OCSP_cert_status_good;
|
||||
break;
|
||||
case ASN1_TAG_EXPLICIT(1):
|
||||
if (asn1_type_from_der(ASN1_TAG_EXPLICIT(1), &p, &len, &d, &dlen) != 1
|
||||
|| asn1_generalized_time_from_der(revocation_time, &p, &len) != 1
|
||||
|| asn1_explicit_from_der(0, &q, &qlen, &p, &len) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (q) {
|
||||
if (x509_crl_reason_from_der(revocation_reason, &q, &qlen) != 1
|
||||
|| asn1_length_is_zero(qlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cert_status = OCSP_cert_status_revoked;
|
||||
break;
|
||||
case ASN1_TAG_IMPLICIT(2):
|
||||
if (asn1_implicit_from_der(2, &p, &len, &d, &dlen) != 1
|
||||
|| len != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*cert_status = OCSP_cert_status_unknown;
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_generalized_time_from_der(this_update, &d, &dlen) != 1
|
||||
|| asn1_explicit_from_der(0, &p, &len, &d, &dlen) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
if (asn1_generalized_time_from_der(next_update, &p, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
*next_update = (time_t)-1;
|
||||
}
|
||||
if (x509_explicit_exts_from_der(1, exts, extslen, &d, &dlen) < 0
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ocsp_revoked_info_print(FILE *fp, int fmt, int ind,
|
||||
const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
time_t tv;
|
||||
int reason;
|
||||
|
||||
if (!d || !dlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_generalized_time_from_der(&tv, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "revocationTime: %s", ctime(&tv));
|
||||
if (asn1_explicit_from_der(0, &p, &len, &d, &dlen) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
if (x509_crl_reason_from_der(&reason, &p, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "revocationReason: %s\n", x509_crl_reason_name(reason));
|
||||
}
|
||||
if (asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const uint32_t oid_pkix_ocsp_crl[] = { 1,3,6,1,5,5,7,48,1,3 };
|
||||
static const uint32_t oid_pkix_ocsp_archive_cutoff[] = { 1,3,6,1,5,5,7,48,1,6 };
|
||||
|
||||
static int ocsp_single_response_ext_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
const uint8_t *d, size_t dlen)
|
||||
{
|
||||
int oid;
|
||||
int critical = -1;
|
||||
uint32_t nodes[32];
|
||||
size_t nodes_cnt = 0;
|
||||
const char *ext_name = NULL;
|
||||
const uint8_t *val;
|
||||
size_t vlen;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
time_t tv;
|
||||
int reason;
|
||||
|
||||
if (!d || !dlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
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
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
|
||||
// extnID
|
||||
if (asn1_object_identifier_equ(nodes, nodes_cnt,
|
||||
oid_pkix_ocsp_crl, oid_cnt(oid_pkix_ocsp_crl))) {
|
||||
oid = OID_pkix_ocsp_crl;
|
||||
ext_name = "CrlID";
|
||||
} else if (asn1_object_identifier_equ(nodes, nodes_cnt,
|
||||
oid_pkix_ocsp_archive_cutoff, oid_cnt(oid_pkix_ocsp_archive_cutoff))) {
|
||||
oid = OID_pkix_ocsp_archive_cutoff;
|
||||
ext_name = "ArchiveCutoff";
|
||||
}
|
||||
switch (oid) {
|
||||
case OID_ce_crl_reasons:
|
||||
case OID_ce_invalidity_date:
|
||||
case OID_ce_certificate_issuer:
|
||||
ext_name = x509_crl_entry_ext_id_name(oid);
|
||||
break;
|
||||
default:
|
||||
ext_name = x509_ext_id_name(oid);
|
||||
}
|
||||
asn1_object_identifier_print(fp, fmt, ind + 4, "extnID", ext_name, nodes, nodes_cnt);
|
||||
|
||||
// critical
|
||||
if (critical != -1) {
|
||||
format_print(fp, fmt, ind + 4, "critical: %s\n", asn1_boolean_name(critical));
|
||||
}
|
||||
|
||||
switch (oid) {
|
||||
case OID_pkix_ocsp_crl:
|
||||
if (asn1_sequence_from_der(&p, &len, &val, &vlen) != 1
|
||||
|| asn1_length_is_zero(vlen) != 1
|
||||
|| ocsp_crl_id_print(fp, fmt, ind + 4, "crlID", p, len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_pkix_ocsp_archive_cutoff:
|
||||
if (ocsp_archive_cutoff_print(fp, fmt, ind + 4, "archiveCutoff", val, vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_ce_crl_reasons:
|
||||
if (x509_crl_reason_from_der(&reason, &val, &vlen) != 1
|
||||
|| asn1_length_is_zero(vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind + 4, "reasonCode: %s\n", x509_crl_reason_name(reason));
|
||||
break;
|
||||
case OID_ce_invalidity_date:
|
||||
if (asn1_generalized_time_from_der(&tv, &val, &vlen) != 1
|
||||
|| asn1_length_is_zero(vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind + 4, "invalidityDate: %s", ctime(&tv));
|
||||
break;
|
||||
case OID_ce_certificate_issuer:
|
||||
if (asn1_sequence_from_der(&p, &len, &val, &vlen) != 1
|
||||
|| asn1_length_is_zero(vlen) != 1
|
||||
|| x509_general_names_print(fp, fmt, ind + 4, "certificateIssuer", p, len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
format_bytes(fp, fmt, ind + 4, "extnValue", val, vlen);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ocsp_single_response_print(FILE *fp, int fmt, int ind, const char *label,
|
||||
const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *seq;
|
||||
size_t seq_len;
|
||||
const uint8_t *cert_id;
|
||||
size_t cert_id_len;
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
const uint8_t *issuer_name_hash;
|
||||
size_t issuer_name_hash_len;
|
||||
const uint8_t *issuer_key_hash;
|
||||
size_t issuer_key_hash_len;
|
||||
const uint8_t *serial_number;
|
||||
size_t serial_number_len;
|
||||
int hash_algor;
|
||||
int cert_status;
|
||||
time_t tv;
|
||||
int tag;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
if (asn1_sequence_from_der(&seq, &seq_len, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// certID
|
||||
format_print(fp, fmt, ind, "certID\n");
|
||||
if (asn1_sequence_from_der(&cert_id, &cert_id_len, &seq, &seq_len) != 1
|
||||
|| x509_digest_algor_from_der(&hash_algor, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_octet_string_from_der(&issuer_name_hash, &issuer_name_hash_len, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_octet_string_from_der(&issuer_key_hash, &issuer_key_hash_len, &cert_id, &cert_id_len) != 1
|
||||
|| asn1_integer_from_der(&serial_number, &serial_number_len, &cert_id, &cert_id_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind + 4, "hashAlgorithm: %s\n", x509_digest_algor_name(hash_algor));
|
||||
format_bytes(fp, fmt, ind + 4, "issuerNameHash", issuer_name_hash, issuer_name_hash_len);
|
||||
format_bytes(fp, fmt, ind + 4, "issuerKeyHash", issuer_key_hash, issuer_key_hash_len);
|
||||
format_bytes(fp, fmt, ind + 4, "serialNumber", serial_number, serial_number_len);
|
||||
if (asn1_length_is_zero(cert_id_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// certStatus
|
||||
if (asn1_tag_from_der_readonly(&tag, &seq, &seq_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
switch (tag) {
|
||||
case ASN1_TAG_IMPLICIT(0):
|
||||
if (asn1_implicit_from_der(0, &p, &len, &seq, &seq_len) != 1 || len != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
cert_status = OCSP_cert_status_good;
|
||||
format_print(fp, fmt, ind, "certStatus: %s\n", ocsp_cert_status_name(cert_status));
|
||||
break;
|
||||
case ASN1_TAG_EXPLICIT(1):
|
||||
if (asn1_type_from_der(ASN1_TAG_EXPLICIT(1), &p, &len, &seq, &seq_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
cert_status = OCSP_cert_status_revoked;
|
||||
format_print(fp, fmt, ind, "certStatus: %s\n", ocsp_cert_status_name(cert_status));
|
||||
if (ocsp_revoked_info_print(fp, fmt, ind + 4, p, len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case ASN1_TAG_IMPLICIT(2):
|
||||
if (asn1_implicit_from_der(2, &p, &len, &seq, &seq_len) != 1 || len != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
cert_status = OCSP_cert_status_unknown;
|
||||
format_print(fp, fmt, ind, "certStatus: %s\n", ocsp_cert_status_name(cert_status));
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// thisUpdate
|
||||
if (asn1_generalized_time_from_der(&tv, &seq, &seq_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "thisUpdate: %s", ctime(&tv));
|
||||
|
||||
// nextUpdate [0]
|
||||
if (asn1_explicit_from_der(0, &p, &len, &seq, &seq_len) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
if (asn1_generalized_time_from_der(&tv, &p, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, fmt, ind, "nextUpdate: %s", ctime(&tv));
|
||||
}
|
||||
|
||||
// singleExtensions [1]
|
||||
if (x509_explicit_exts_from_der(1, &p, &len, &seq, &seq_len) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
format_print(fp, fmt, ind, "singleExtensions\n");
|
||||
}
|
||||
while (len) {
|
||||
const uint8_t *ext;
|
||||
size_t ext_len;
|
||||
|
||||
if (asn1_sequence_from_der(&ext, &ext_len, &p, &len) != 1
|
||||
|| ocsp_single_response_ext_print(fp, fmt, ind + 4, "Extension", ext, ext_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (asn1_length_is_zero(seq_len) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
131
tests/ocsptest.c
131
tests/ocsptest.c
@@ -14,6 +14,7 @@
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/x509_crl.h>
|
||||
#include <gmssl/ocsp.h>
|
||||
|
||||
|
||||
@@ -233,8 +234,138 @@ static int test_ocsp_request_vector(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_ocsp_single_response(void)
|
||||
{
|
||||
uint8_t exts[128];
|
||||
uint8_t *p = exts;
|
||||
size_t extslen = 0;
|
||||
uint8_t buf[256];
|
||||
const uint8_t *cp;
|
||||
size_t len;
|
||||
int hash_algor;
|
||||
const uint8_t *name_hash;
|
||||
size_t name_hash_len;
|
||||
const uint8_t *key_hash;
|
||||
size_t key_hash_len;
|
||||
const uint8_t *serial;
|
||||
size_t serial_len;
|
||||
int cert_status;
|
||||
time_t revocation_time;
|
||||
int revocation_reason;
|
||||
time_t this_update;
|
||||
time_t next_update;
|
||||
const uint8_t *single_response_exts;
|
||||
size_t single_response_exts_len;
|
||||
|
||||
/*
|
||||
if (ocsp_crl_id_print(stderr, 0, 0, "CrlID", NULL, 0) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
uint8_t crl_url[64];
|
||||
uint8_t *crl_url_p = crl_url;
|
||||
size_t crl_url_len = 0;
|
||||
uint8_t crl_id[128];
|
||||
uint8_t *crl_id_p = crl_id;
|
||||
size_t crl_id_len = 0;
|
||||
const char *uri = "http://example.com/root.crl";
|
||||
|
||||
if (asn1_ia5_string_to_der(uri, strlen(uri), &crl_url_p, &crl_url_len) != 1
|
||||
|| asn1_explicit_to_der(0, crl_url, crl_url_len, &crl_id_p, &crl_id_len) != 1
|
||||
|| ocsp_crl_id_print(stderr, 0, 0, "CrlID", crl_id, crl_id_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (x509_crl_reason_ext_to_der(-1, X509_cr_key_compromise, &p, &extslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
len = 0;
|
||||
if (ocsp_single_response_to_der(OID_sm3,
|
||||
issuer_name_hash, sizeof(issuer_name_hash),
|
||||
issuer_key_hash, sizeof(issuer_key_hash),
|
||||
serial_number, sizeof(serial_number),
|
||||
OCSP_cert_status_revoked, 1700000000, X509_cr_key_compromise,
|
||||
1700003600, 1700007200, exts, extslen, &p, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
ocsp_single_response_print(stderr, 0, 0, "SingleResponse", buf, len);
|
||||
|
||||
cp = buf;
|
||||
if (ocsp_single_response_from_der(&hash_algor,
|
||||
&name_hash, &name_hash_len,
|
||||
&key_hash, &key_hash_len,
|
||||
&serial, &serial_len,
|
||||
&cert_status, &revocation_time, &revocation_reason,
|
||||
&this_update, &next_update,
|
||||
&single_response_exts, &single_response_exts_len, &cp, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1
|
||||
|| hash_algor != OID_sm3
|
||||
|| name_hash_len != sizeof(issuer_name_hash)
|
||||
|| memcmp(name_hash, issuer_name_hash, sizeof(issuer_name_hash)) != 0
|
||||
|| key_hash_len != sizeof(issuer_key_hash)
|
||||
|| memcmp(key_hash, issuer_key_hash, sizeof(issuer_key_hash)) != 0
|
||||
|| serial_len != sizeof(serial_number)
|
||||
|| memcmp(serial, serial_number, sizeof(serial_number)) != 0
|
||||
|| cert_status != OCSP_cert_status_revoked
|
||||
|| revocation_time != 1700000000
|
||||
|| revocation_reason != X509_cr_key_compromise
|
||||
|| this_update != 1700003600
|
||||
|| next_update != 1700007200
|
||||
|| single_response_exts_len != extslen
|
||||
|| memcmp(single_response_exts, exts, extslen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
len = 0;
|
||||
if (ocsp_single_response_to_der(OID_sm3,
|
||||
issuer_name_hash, sizeof(issuer_name_hash),
|
||||
issuer_key_hash, sizeof(issuer_key_hash),
|
||||
serial_number, sizeof(serial_number),
|
||||
OCSP_cert_status_good, -1, -1,
|
||||
1700003600, -1, NULL, 0, &p, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
ocsp_single_response_print(stderr, 0, 0, "SingleResponse", buf, len);
|
||||
|
||||
cp = buf;
|
||||
if (ocsp_single_response_from_der(&hash_algor,
|
||||
&name_hash, &name_hash_len,
|
||||
&key_hash, &key_hash_len,
|
||||
&serial, &serial_len,
|
||||
&cert_status, &revocation_time, &revocation_reason,
|
||||
&this_update, &next_update,
|
||||
&single_response_exts, &single_response_exts_len, &cp, &len) != 1
|
||||
|| asn1_length_is_zero(len) != 1
|
||||
|| hash_algor != OID_sm3
|
||||
|| cert_status != OCSP_cert_status_good
|
||||
|| revocation_time != (time_t)-1
|
||||
|| revocation_reason != -1
|
||||
|| this_update != 1700003600
|
||||
|| next_update != (time_t)-1
|
||||
|| single_response_exts != NULL
|
||||
|| single_response_exts_len != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_ocsp_single_response() != 1) goto err;
|
||||
if (test_ocsp_request_item() != 1) goto err;
|
||||
if (test_ocsp_request() != 1) goto err;
|
||||
#ifdef ENABLE_SHA1
|
||||
|
||||
Reference in New Issue
Block a user