mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-28 16:53:37 +08:00
Update OCSP
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
120
src/ocsp.c
120
src/ocsp.c
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
45
src/tls13.c
45
src/tls13.c
@@ -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) {
|
||||||
|
|||||||
@@ -1929,9 +1929,31 @@ 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,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user