Update OCSP

This commit is contained in:
Zhi Guan
2026-06-19 11:56:45 +08:00
parent 12aeed4986
commit 47c9fa8e4f
11 changed files with 302 additions and 28 deletions

View File

@@ -820,7 +820,7 @@ endif()
# #
set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_NAME "GmSSL")
set(CPACK_PACKAGE_VENDOR "GmSSL develop team") set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1102") set(CPACK_PACKAGE_VERSION "3.2.0-dev.1103")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MODIFY_PATH ON)
include(CPack) include(CPack)

View File

@@ -313,6 +313,9 @@ int ocsp_verify(OCSP_SIGN_CTX *ctx,
const uint8_t *signer_cert, size_t signer_cert_len, const uint8_t *signer_cert, size_t signer_cert_len,
const char *signer_id, size_t signer_id_len, const char *signer_id, size_t signer_id_len,
int *reason); int *reason);
int ocsp_response_get_signer_cert(const uint8_t *resp, size_t resplen,
const uint8_t *certs, size_t certs_len,
const uint8_t **signer_cert, size_t *signer_cert_len);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -18,7 +18,7 @@ extern "C" {
#define GMSSL_VERSION_NUM 30200 #define GMSSL_VERSION_NUM 30200
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1102" #define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1103"
int gmssl_version_num(void); int gmssl_version_num(void);
const char *gmssl_version_str(void); const char *gmssl_version_str(void);

View File

@@ -329,6 +329,7 @@ typedef enum {
X509_cert_ca, X509_cert_ca,
X509_cert_root_ca, X509_cert_root_ca,
X509_cert_crl_sign, X509_cert_crl_sign,
X509_cert_ocsp_signing,
} X509_CERT_TYPE; } X509_CERT_TYPE;
int x509_cert_check(const uint8_t *cert, size_t certlen, int cert_type); int x509_cert_check(const uint8_t *cert, size_t certlen, int cert_type);
@@ -338,6 +339,9 @@ int x509_cert_check_name_constraints(const uint8_t *cert, size_t certlen,
int x509_cert_is_self_issued(const uint8_t *cert, size_t certlen); int x509_cert_is_self_issued(const uint8_t *cert, size_t certlen);
int x509_tlcp_cert_pair_entity_match(const uint8_t *sign_cert, size_t sign_certlen, int x509_tlcp_cert_pair_entity_match(const uint8_t *sign_cert, size_t sign_certlen,
const uint8_t *kenc_cert, size_t kenc_certlen); const uint8_t *kenc_cert, size_t kenc_certlen);
int x509_cert_verify_by_ocsp_response(const uint8_t *cert, size_t certlen,
const uint8_t *issuer_cert, size_t issuer_certlen,
const uint8_t *ocsp, size_t ocsp_len);
/* /*
IssuerAndSerialNumber ::= SEQUENCE { IssuerAndSerialNumber ::= SEQUENCE {
@@ -382,10 +386,12 @@ typedef enum {
int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type, int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
const uint8_t *rootcerts, size_t rootcertslen, const uint8_t *rootcerts, size_t rootcertslen,
const uint8_t *crl, size_t crl_len, const uint8_t *crl, size_t crl_len,
const uint8_t *ocsp, size_t ocsp_len,
int depth, int *verify_result); int depth, int *verify_result);
int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type, int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type,
const uint8_t *rootcerts, size_t rootcertslen, const uint8_t *rootcerts, size_t rootcertslen,
const uint8_t *crl, size_t crl_len, const uint8_t *crl, size_t crl_len,
const uint8_t *ocsp, size_t ocsp_len,
int depth, int *verify_result); int depth, int *verify_result);
int x509_certs_check_name_constraints(const uint8_t *cert_chain, size_t cert_chain_len, int x509_certs_check_name_constraints(const uint8_t *cert_chain, size_t cert_chain_len,
const uint8_t *rootcacert, size_t rootcacertlen); const uint8_t *rootcacert, size_t rootcacertlen);

View File

@@ -2549,3 +2549,123 @@ int ocsp_verify(OCSP_SIGN_CTX *ctx,
return -1; return -1;
} }
} }
static int ocsp_response_find_signer_cert_in_certs(int responder_id_type,
const uint8_t *responder_id, size_t responder_id_len,
const uint8_t *certs, size_t certs_len,
const uint8_t **signer_cert, size_t *signer_cert_len)
{
const uint8_t *cert;
size_t cert_len;
int ret;
if (!responder_id || !responder_id_len || !signer_cert || !signer_cert_len
|| (!certs && certs_len)) {
error_print();
return -1;
}
while (certs_len) {
if (x509_cert_from_der(&cert, &cert_len, &certs, &certs_len) != 1) {
error_print();
return -1;
}
if ((ret = ocsp_verify_responder_id(responder_id_type,
responder_id, responder_id_len, cert, cert_len)) < 0) {
error_print();
return -1;
}
if (ret == 1) {
*signer_cert = cert;
*signer_cert_len = cert_len;
return 1;
}
}
*signer_cert = NULL;
*signer_cert_len = 0;
return 0;
}
int ocsp_response_get_signer_cert(const uint8_t *resp, size_t resplen,
const uint8_t *certs, size_t certs_len,
const uint8_t **signer_cert, size_t *signer_cert_len)
{
const uint8_t *p;
size_t len;
int response_status;
const uint8_t *basic_response;
size_t basic_response_len;
const uint8_t *response_data;
size_t response_data_len;
int signature_algor;
const uint8_t *signature;
size_t signature_len;
const uint8_t *embedded_certs;
size_t embedded_certs_len;
int responder_id_type;
const uint8_t *responder_id;
size_t responder_id_len;
time_t produced_at;
const uint8_t *single_response_first;
size_t single_response_first_len;
const uint8_t *single_response_others;
size_t single_response_others_len;
const uint8_t *response_exts;
size_t response_exts_len;
int ret;
if (!resp || !resplen || (!certs && certs_len) || !signer_cert || !signer_cert_len) {
error_print();
return -1;
}
*signer_cert = NULL;
*signer_cert_len = 0;
p = resp;
len = resplen;
if (ocsp_response_from_der(&response_status, &basic_response, &basic_response_len,
&p, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (response_status != OCSP_response_status_successful) {
return 0;
}
p = basic_response;
len = basic_response_len;
if (ocsp_basic_response_from_der(&response_data, &response_data_len,
&signature_algor, &signature, &signature_len,
&embedded_certs, &embedded_certs_len, &p, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
p = response_data;
len = response_data_len;
if (ocsp_response_data_from_der(&responder_id_type,
&responder_id, &responder_id_len,
&produced_at,
&single_response_first, &single_response_first_len,
&single_response_others, &single_response_others_len,
&response_exts, &response_exts_len,
&p, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (certs_len) {
if ((ret = ocsp_response_find_signer_cert_in_certs(responder_id_type,
responder_id, responder_id_len,
certs, certs_len,
signer_cert, signer_cert_len)) != 0) {
return ret;
}
}
if (embedded_certs_len) {
return ocsp_response_find_signer_cert_in_certs(responder_id_type,
responder_id, responder_id_len,
embedded_certs, embedded_certs_len,
signer_cert, signer_cert_len);
}
return 0;
}

View File

@@ -809,6 +809,7 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn)
if (conn->ctx->cacertslen) { if (conn->ctx->cacertslen) {
if (x509_certs_verify_tlcp(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, if (x509_certs_verify_tlcp(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0, conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0,
NULL, 0,
conn->ctx->verify_depth, &verify_result) != 1) { conn->ctx->verify_depth, &verify_result) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_bad_certificate); tls_send_alert(conn, TLS_alert_bad_certificate);

View File

@@ -1286,6 +1286,7 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
if (conn->ctx->cacertslen) { if (conn->ctx->cacertslen) {
if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0, conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0,
NULL, 0,
conn->ctx->verify_depth, &verify_result) != 1) { conn->ctx->verify_depth, &verify_result) != 1) {
error_print(); error_print();
conn->verify_result = verify_result; conn->verify_result = verify_result;
@@ -2586,6 +2587,7 @@ int tls_recv_client_certificate(TLS_CONNECT *conn)
} }
if (x509_certs_verify(conn->client_certs, conn->client_certs_len, X509_cert_chain_client, if (x509_certs_verify(conn->client_certs, conn->client_certs_len, X509_cert_chain_client,
conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0, conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0,
NULL, 0,
verify_depth, &verify_result) != 1) { verify_depth, &verify_result) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_bad_certificate); tls_send_alert(conn, TLS_alert_bad_certificate);

View File

@@ -6158,8 +6158,8 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn)
int ret; int ret;
const uint8_t *request_context; const uint8_t *request_context;
size_t request_context_len; size_t request_context_len;
const uint8_t *leaf_status_request_ocsp_response; const uint8_t *leaf_status_request_ocsp_response = NULL;
size_t leaf_status_request_ocsp_response_len; size_t leaf_status_request_ocsp_response_len = 0;
const uint8_t *leaf_signed_certificate_timestamp; const uint8_t *leaf_signed_certificate_timestamp;
size_t leaf_signed_certificate_timestamp_len; size_t leaf_signed_certificate_timestamp_len;
const uint8_t *cert; const uint8_t *cert;
@@ -6258,25 +6258,21 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn)
// 验证一个证书链之前,应该首先判断一下这个证书链对应的根证书是否存在 // 验证一个证书链之前,应该首先判断一下这个证书链对应的根证书是否存在
// 如果我们没有根证书,那么就根本不能验证 // 如果我们没有根证书,那么就根本不能验证
// 把查找根证书和验证证书链的函数分开 // 把查找根证书和验证证书链的函数分开
if (x509_certs_verify( ret = x509_certs_verify(
conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->cacerts, conn->ctx->cacertslen,
NULL, 0, NULL, 0,
conn->ctx->verify_depth, &verify_result) != 1) { leaf_status_request_ocsp_response, leaf_status_request_ocsp_response_len,
conn->ctx->verify_depth, &verify_result);
if (ret < 0) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_bad_certificate); tls13_send_alert(conn, TLS_alert_bad_certificate);
return -1; return -1;
} }
// status_request if (ret == 0) {
if (leaf_status_request_ocsp_response) { error_print();
if (ocsp_response_verify( tls13_send_alert(conn, TLS_alert_certificate_revoked);
leaf_status_request_ocsp_response, return -1;
leaf_status_request_ocsp_response_len,
conn->ctx->cacerts, conn->ctx->cacertslen) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_certificate_revoked);
return -1;
}
} }
// signed_certificate_timestamp // signed_certificate_timestamp
if (leaf_signed_certificate_timestamp) { if (leaf_signed_certificate_timestamp) {
@@ -8514,7 +8510,7 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn)
const uint8_t *request_context; const uint8_t *request_context;
size_t request_context_len; size_t request_context_len;
const uint8_t *status_request_ocsp_response = NULL; const uint8_t *status_request_ocsp_response = NULL;
size_t status_request_ocsp_response_len; size_t status_request_ocsp_response_len = 0;
const uint8_t *signed_certificate_timestamp = NULL; const uint8_t *signed_certificate_timestamp = NULL;
size_t signed_certificate_timestamp_len; size_t signed_certificate_timestamp_len;
const uint8_t *cert; const uint8_t *cert;
@@ -8618,23 +8614,20 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn)
} }
// verify client cert_chain // verify client cert_chain
if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_client, ret = x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_client,
conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->cacerts, conn->ctx->cacertslen,
NULL, 0, NULL, 0,
conn->ctx->verify_depth, &verify_result) != 1) { status_request_ocsp_response, status_request_ocsp_response_len,
conn->ctx->verify_depth, &verify_result);
if (ret < 0) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_bad_certificate); tls13_send_alert(conn, TLS_alert_bad_certificate);
return -1; return -1;
} }
// status_request if (ret == 0) {
if (status_request_ocsp_response) { error_print();
if (ocsp_response_verify( tls13_send_alert(conn, TLS_alert_certificate_revoked);
status_request_ocsp_response, status_request_ocsp_response_len, return -1;
conn->ctx->cacerts, conn->ctx->cacertslen) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_certificate_revoked);
return -1;
}
} }
// signed_certificate_timestamp // signed_certificate_timestamp
if (signed_certificate_timestamp) { if (signed_certificate_timestamp) {

View File

@@ -1928,10 +1928,32 @@ static int x509_cert_check_optional_crl(const uint8_t *cert, size_t certlen,
} }
return ret; return ret;
} }
static int x509_cert_check_optional_ocsp(const uint8_t *cert, size_t certlen,
const uint8_t *issuer_cert, size_t issuer_certlen,
const uint8_t *ocsp, size_t ocsp_len)
{
int ret;
if (!ocsp && ocsp_len == 0) {
return 1;
}
if (!cert || !certlen || !issuer_cert || !issuer_certlen || !ocsp || !ocsp_len) {
error_print();
return -1;
}
if ((ret = x509_cert_verify_by_ocsp_response(cert, certlen,
issuer_cert, issuer_certlen, ocsp, ocsp_len)) < 0) {
error_print();
return -1;
}
return ret;
}
int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type, int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
const uint8_t *rootcerts, size_t rootcertslen, const uint8_t *rootcerts, size_t rootcertslen,
const uint8_t *crl, size_t crl_len, const uint8_t *crl, size_t crl_len,
const uint8_t *ocsp, size_t ocsp_len,
int depth, int *verify_result) int depth, int *verify_result)
{ {
int entity_cert_type; int entity_cert_type;
@@ -2007,6 +2029,17 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
error_print(); error_print();
return -1; return -1;
} }
if (path_len == 0) {
if ((ret = x509_cert_check_optional_ocsp(cert, certlen,
cacert, cacertlen, ocsp, ocsp_len)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
error_print();
return 0;
}
}
cert = cacert; cert = cacert;
certlen = cacertlen; certlen = cacertlen;
@@ -2031,6 +2064,17 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
error_print(); error_print();
return -1; return -1;
} }
if (path_len == 0) {
if ((ret = x509_cert_check_optional_ocsp(cert, certlen,
cacert, cacertlen, ocsp, ocsp_len)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
error_print();
return 0;
}
}
if (x509_certs_check_basic_constraints(cert_chain, cert_chain_len, if (x509_certs_check_basic_constraints(cert_chain, cert_chain_len,
cacert, cacertlen) != 1) { cacert, cacertlen) != 1) {
@@ -2053,6 +2097,7 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type, int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type,
const uint8_t *rootcerts, size_t rootcertslen, const uint8_t *rootcerts, size_t rootcertslen,
const uint8_t *crl, size_t crl_len, const uint8_t *crl, size_t crl_len,
const uint8_t *ocsp, size_t ocsp_len,
int depth, int *verify_result) int depth, int *verify_result)
{ {
int sign_cert_type; int sign_cert_type;
@@ -2164,6 +2209,26 @@ int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type
error_print(); error_print();
return -1; return -1;
} }
if (path_len == 0) {
if ((ret = x509_cert_check_optional_ocsp(cert, certlen,
cacert, cacertlen, ocsp, ocsp_len)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
error_print();
return 0;
}
if ((ret = x509_cert_check_optional_ocsp(kenc_cert, kenc_certlen,
cacert, cacertlen, ocsp, ocsp_len)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
error_print();
return 0;
}
}
cert = cacert; cert = cacert;
certlen = cacertlen; certlen = cacertlen;
@@ -2196,6 +2261,24 @@ int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type
error_print(); error_print();
return -1; return -1;
} }
if ((ret = x509_cert_check_optional_ocsp(cert, certlen,
cacert, cacertlen, ocsp, ocsp_len)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
error_print();
return 0;
}
if ((ret = x509_cert_check_optional_ocsp(kenc_cert, kenc_certlen,
cacert, cacertlen, ocsp, ocsp_len)) < 0) {
error_print();
return -1;
}
if (ret == 0) {
error_print();
return 0;
}
} }
if (x509_certs_check_basic_constraints_tlcp(cert_chain, cert_chain_len, if (x509_certs_check_basic_constraints_tlcp(cert_chain, cert_chain_len,

View File

@@ -1381,6 +1381,7 @@ int x509_key_usage_check(int bits, int cert_type)
break; break;
case X509_cert_server_auth: case X509_cert_server_auth:
case X509_cert_client_auth: case X509_cert_client_auth:
case X509_cert_ocsp_signing:
if (!(bits & X509_KU_DIGITAL_SIGNATURE)) { if (!(bits & X509_KU_DIGITAL_SIGNATURE)) {
error_print(); error_print();
return -1; return -1;
@@ -2170,6 +2171,7 @@ int x509_basic_constraints_check(int ca, int path_len_constraint, int cert_type)
case X509_cert_client_auth: case X509_cert_client_auth:
case X509_cert_server_key_encipher: case X509_cert_server_key_encipher:
case X509_cert_client_key_encipher: case X509_cert_client_key_encipher:
case X509_cert_ocsp_signing:
if (ca > 0 || path_len_constraint != -1) { if (ca > 0 || path_len_constraint != -1) {
error_print(); error_print();
return -1; return -1;
@@ -2613,6 +2615,11 @@ int x509_ext_key_usage_check(const int *oids, size_t oids_cnt, int cert_type)
return 1; return 1;
} }
break; break;
case X509_cert_ocsp_signing:
if (oids[i] == OID_kp_ocsp_signing) {
return 1;
}
break;
default: default:
error_print(); error_print();

View File

@@ -18,6 +18,7 @@
#include <gmssl/x509_ext.h> #include <gmssl/x509_ext.h>
#include <gmssl/x509_cer.h> #include <gmssl/x509_cer.h>
#include <gmssl/x509_crl.h> #include <gmssl/x509_crl.h>
#include <gmssl/ocsp.h>
#include <gmssl/error.h> #include <gmssl/error.h>
@@ -418,6 +419,7 @@ int x509_cert_check_subject(const uint8_t *cert, size_t certlen, int cert_type)
case X509_cert_client_auth: case X509_cert_client_auth:
case X509_cert_server_key_encipher: case X509_cert_server_key_encipher:
case X509_cert_client_key_encipher: case X509_cert_client_key_encipher:
case X509_cert_ocsp_signing:
is_cacert = 0; is_cacert = 0;
break; break;
case X509_cert_ca: case X509_cert_ca:
@@ -2003,6 +2005,7 @@ static int x509_cert_check_basic_constraints_by_type(const uint8_t *cert, size_t
case X509_cert_client_auth: case X509_cert_client_auth:
case X509_cert_server_key_encipher: case X509_cert_server_key_encipher:
case X509_cert_client_key_encipher: case X509_cert_client_key_encipher:
case X509_cert_ocsp_signing:
is_ca = 0; is_ca = 0;
break; break;
case X509_cert_ca: case X509_cert_ca:
@@ -2615,3 +2618,59 @@ int x509_cert_is_revoked_by_crl(const uint8_t *cert, size_t certlen,
} }
return ret; return ret;
} }
int x509_cert_verify_by_ocsp_response(const uint8_t *cert, size_t certlen,
const uint8_t *issuer_cert, size_t issuer_certlen,
const uint8_t *ocsp, size_t ocsp_len)
{
uint8_t req[OCSP_MAX_REQUEST_SIZE];
size_t reqlen;
OCSP_SIGN_CTX ctx;
const uint8_t *signer_cert;
size_t signer_certlen;
int signer_is_issuer;
int reason;
int ret;
if (!cert || !certlen || !issuer_cert || !issuer_certlen || !ocsp || !ocsp_len) {
error_print();
return -1;
}
if (ocsp_request_generate(req, &reqlen, sizeof(req),
cert, certlen, issuer_cert, issuer_certlen, DIGEST_sm3()) != 1
|| ocsp_verify_init(&ctx, req, reqlen, issuer_cert, issuer_certlen) != 1) {
error_print();
return -1;
}
if ((ret = ocsp_response_get_signer_cert(ocsp, ocsp_len,
issuer_cert, issuer_certlen, &signer_cert, &signer_certlen)) < 0) {
error_print();
return 0;
}
if (ret == 0) {
return 0;
}
signer_is_issuer = (signer_certlen == issuer_certlen
&& memcmp(signer_cert, issuer_cert, issuer_certlen) == 0);
if (!signer_is_issuer) {
if (x509_cert_verify_by_ca_cert(signer_cert, signer_certlen,
issuer_cert, issuer_certlen,
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return 0;
}
if (x509_cert_check(signer_cert, signer_certlen, X509_cert_ocsp_signing) != 1) {
error_print();
return 0;
}
}
ret = ocsp_verify(&ctx, ocsp, ocsp_len,
signer_cert, signer_certlen,
NULL, 0, &reason);
if (ret != 1) {
return 0;
}
return 1;
}