diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cc54614..b5058f56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -820,7 +820,7 @@ endif() # set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_VENDOR "GmSSL develop team") -set(CPACK_PACKAGE_VERSION "3.2.0-dev.1101") +set(CPACK_PACKAGE_VERSION "3.2.0-dev.1102") set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_NSIS_MODIFY_PATH ON) include(CPack) diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 213a129c..39bc7c57 100644 --- a/include/gmssl/version.h +++ b/include/gmssl/version.h @@ -18,7 +18,7 @@ extern "C" { #define GMSSL_VERSION_NUM 30200 -#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1101" +#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1102" int gmssl_version_num(void); const char *gmssl_version_str(void); diff --git a/include/gmssl/x509_cer.h b/include/gmssl/x509_cer.h index e97a9639..fff9cad2 100644 --- a/include/gmssl/x509_cer.h +++ b/include/gmssl/x509_cer.h @@ -380,9 +380,13 @@ typedef enum { //int x509_cert_chain_verify(const uint8_t *certs, size_t certslen, // const uint8_t *cacerts, size_t cacertslen, int depth, int *verify_result); int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result); + const uint8_t *rootcerts, size_t rootcertslen, + const uint8_t *crl, size_t crl_len, + int depth, int *verify_result); int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result); + const uint8_t *rootcerts, size_t rootcertslen, + const uint8_t *crl, size_t crl_len, + int depth, int *verify_result); int x509_certs_check_name_constraints(const uint8_t *cert_chain, size_t cert_chain_len, const uint8_t *rootcacert, size_t rootcacertlen); int x509_certs_check_basic_constraints(const uint8_t *cert_chain, size_t cert_chain_len, diff --git a/include/gmssl/x509_crl.h b/include/gmssl/x509_crl.h index a76052a5..6b3a2024 100644 --- a/include/gmssl/x509_crl.h +++ b/include/gmssl/x509_crl.h @@ -295,6 +295,8 @@ int x509_crl_get_revoked_certs(const uint8_t *a, size_t alen, const uint8_t **d, 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_cert_is_revoked_by_crl(const uint8_t *cert, size_t certlen, + const uint8_t *crl, size_t crl_len); int x509_crls_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); diff --git a/src/tlcp.c b/src/tlcp.c index 54554c0b..b9172d97 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -808,7 +808,8 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn) if (conn->ctx->cacertslen) { if (x509_certs_verify_tlcp(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, - conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) { + conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0, + conn->ctx->verify_depth, &verify_result) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_certificate); return -1; diff --git a/src/tls12.c b/src/tls12.c index 67b9df2a..6f03f3a7 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -1285,7 +1285,8 @@ int tls_recv_server_certificate(TLS_CONNECT *conn) // verify server Certificate if (conn->ctx->cacertslen) { if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, - conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) { + conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0, + conn->ctx->verify_depth, &verify_result) != 1) { error_print(); conn->verify_result = verify_result; tls_send_alert(conn, TLS_alert_bad_certificate); @@ -2584,7 +2585,8 @@ int tls_recv_client_certificate(TLS_CONNECT *conn) return -1; } if (x509_certs_verify(conn->client_certs, conn->client_certs_len, X509_cert_chain_client, - conn->ctx->cacerts, conn->ctx->cacertslen, verify_depth, &verify_result) != 1) { + conn->ctx->cacerts, conn->ctx->cacertslen, NULL, 0, + verify_depth, &verify_result) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_certificate); return -1; diff --git a/src/tls13.c b/src/tls13.c index fe1289a4..0f0a8a29 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -6261,6 +6261,7 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn) 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->verify_depth, &verify_result) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_bad_certificate); @@ -8619,6 +8620,7 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn) // verify client cert_chain if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_client, conn->ctx->cacerts, conn->ctx->cacertslen, + NULL, 0, conn->ctx->verify_depth, &verify_result) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_bad_certificate); diff --git a/src/x509_cer.c b/src/x509_cer.c index 141a7948..6d91db3b 100644 --- a/src/x509_cer.c +++ b/src/x509_cer.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -1892,9 +1893,46 @@ int x509_cert_check(const uint8_t *cert, size_t certlen, int cert_type) } // 这个函数应该打印到底是哪个证书验证出错了 + +static int x509_cert_check_optional_crl(const uint8_t *cert, size_t certlen, + const uint8_t *crl, size_t crl_len) +{ + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *crl_issuer; + size_t crl_issuer_len; + int ret; + + if (!crl && crl_len == 0) { + return 0; + } + if (!cert || !certlen || !crl || !crl_len) { + error_print(); + return -1; + } + if (x509_cert_get_issuer(cert, certlen, &issuer, &issuer_len) != 1 + || x509_crl_get_issuer(crl, crl_len, &crl_issuer, &crl_issuer_len) != 1) { + error_print(); + return -1; + } + if ((ret = x509_name_equ(issuer, issuer_len, crl_issuer, crl_issuer_len)) < 0) { + error_print(); + return -1; + } + if (ret == 0) { + return 0; + } + if ((ret = x509_cert_is_revoked_by_crl(cert, certlen, crl, crl_len)) < 0) { + error_print(); + return -1; + } + return ret; +} int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result) + const uint8_t *rootcerts, size_t rootcertslen, + const uint8_t *crl, size_t crl_len, + int depth, int *verify_result) { int entity_cert_type; const uint8_t *cert_chain = certs; @@ -1929,6 +1967,14 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type, x509_cert_print(stderr, 0, 10, "Invalid Entity Certificate", cert, certlen); return -1; } + if ((ret = x509_cert_check_optional_crl(cert, certlen, crl, crl_len)) < 0) { + error_print(); + return -1; + } + if (ret == 1) { + error_print(); + return 0; + } while (certslen) { @@ -1941,6 +1987,14 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type, x509_cert_print(stderr, 0, 10, "Invalid CA Certificate", cacert, cacertlen); return -1; } + if ((ret = x509_cert_check_optional_crl(cacert, cacertlen, crl, crl_len)) < 0) { + error_print(); + return -1; + } + if (ret == 1) { + error_print(); + return 0; + } if (path_len > depth) { error_print(); @@ -1997,7 +2051,9 @@ 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, - const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result) + const uint8_t *rootcerts, size_t rootcertslen, + const uint8_t *crl, size_t crl_len, + int depth, int *verify_result) { int sign_cert_type; int kenc_cert_type; @@ -2035,6 +2091,14 @@ int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type error_print(); return -1; } + if ((ret = x509_cert_check_optional_crl(cert, certlen, crl, crl_len)) < 0) { + error_print(); + return -1; + } + if (ret == 1) { + error_print(); + return 0; + } // entity key encipherment cert if (x509_cert_from_der(&kenc_cert, &kenc_certlen, &certs, &certslen) != 1) { @@ -2045,6 +2109,14 @@ int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type error_print(); return -1; } + if ((ret = x509_cert_check_optional_crl(kenc_cert, kenc_certlen, crl, crl_len)) < 0) { + error_print(); + return -1; + } + if (ret == 1) { + error_print(); + return 0; + } if ((ret = x509_tlcp_cert_pair_entity_match(cert, certlen, kenc_cert, kenc_certlen)) < 0) { error_print(); @@ -2065,6 +2137,14 @@ int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, int certs_type error_print(); return -1; } + if ((ret = x509_cert_check_optional_crl(cacert, cacertlen, crl, crl_len)) < 0) { + error_print(); + return -1; + } + if (ret == 1) { + error_print(); + return 0; + } if (path_len == 0) { // verify entity key encipherment cert diff --git a/src/x509_vrf.c b/src/x509_vrf.c index 1c85e5e1..b472bccc 100644 --- a/src/x509_vrf.c +++ b/src/x509_vrf.c @@ -10,12 +10,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include @@ -2571,3 +2573,45 @@ int x509_tlcp_cert_pair_entity_match(const uint8_t *sign_cert, size_t sign_certl match = 1; return match; } + +int x509_cert_is_revoked_by_crl(const uint8_t *cert, size_t certlen, + const uint8_t *crl, size_t crl_len) +{ + const uint8_t *issuer; + size_t issuer_len; + const uint8_t *serial; + size_t serial_len; + const uint8_t *crl_issuer; + size_t crl_issuer_len; + time_t revoke_date; + const uint8_t *crl_entry_exts; + size_t crl_entry_exts_len; + int ret; + + if (!cert || !certlen || !crl || !crl_len) { + error_print(); + return -1; + } + if (x509_cert_get_issuer_and_serial_number(cert, certlen, + &issuer, &issuer_len, &serial, &serial_len) != 1 + || x509_crl_get_issuer(crl, crl_len, &crl_issuer, &crl_issuer_len) != 1) { + error_print(); + return -1; + } + if ((ret = x509_name_equ(issuer, issuer_len, crl_issuer, crl_issuer_len)) != 1) { + if (ret < 0) error_print(); + else error_print(); + return -1; + } + if (x509_crl_check(crl, crl_len, time(NULL)) != 1) { + error_print(); + return -1; + } + if ((ret = x509_crl_find_revoked_cert_by_serial_number(crl, crl_len, + serial, serial_len, &revoke_date, + &crl_entry_exts, &crl_entry_exts_len)) < 0) { + error_print(); + return -1; + } + return ret; +}