Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ set(CMAKE_MACOSX_RPATH TRUE)
# micro version is changed with a set of small changes or bugfixes anywhere in the project.
set(LIBNETCONF2_MAJOR_VERSION 4)
set(LIBNETCONF2_MINOR_VERSION 6)
set(LIBNETCONF2_MICRO_VERSION 1)
set(LIBNETCONF2_MICRO_VERSION 2)
set(LIBNETCONF2_VERSION ${LIBNETCONF2_MAJOR_VERSION}.${LIBNETCONF2_MINOR_VERSION}.${LIBNETCONF2_MICRO_VERSION})

# Version of the library
Expand Down
5 changes: 3 additions & 2 deletions doc/libnetconf.doc
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,9 @@
*
* You may also choose to use a Certificate Revocation List. These lists
* are downloaded from the URIs specified in the x509 CRLDistributionPoints extensions.
* Be mindful that if any CRL is successfully downloaded and set, then at least one of them has to belong
* to the peer (e.g. the client) certificate (in other words it has to be issued by peer's CA).
* Every certificate in the peer's chain that a CRL was obtained for is then checked for revocation.
* Be mindful that a certificate issued by a CA which publishes no CRL, or whose CRL could not be
* downloaded, is accepted with a warning, because its revocation status can not be determined.
*
* Functions List
* --------------
Expand Down
2 changes: 2 additions & 0 deletions src/session_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,8 @@ nc_tls_verify_cert_chain_crl_wrap(void *cert_chain, void *cert_store, void *crl_
return 0;
}

/* CAs with no CRL in the store are silently left unchecked by MbedTLS, which is the
* behavior the OpenSSL backend emulates with its verification callback */
ret = mbedtls_x509_crt_verify((mbedtls_x509_crt *)peer_chain,
(mbedtls_x509_crt *)trust_ca, (mbedtls_x509_crl *)ca_crl,
NULL, &flags, NULL, NULL);
Expand Down
45 changes: 44 additions & 1 deletion src/session_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,47 @@ nc_tls_get_peer_cert_chain_wrap(void *tls_session)
return SSL_get0_verified_chain(tls_session);
}

/**
* @brief Certificate chain verification callback tolerating missing CRLs.
*
* CRL checking is enabled for the whole chain, but not every CA in a chain publishes a CRL
* (offline root CAs typically do not and intermediate certificates often have no CRL distribution
* point at all). Treat a certificate with no CRL available as unchecked instead of failing the
* whole verification, so that revocation is still enforced for every certificate a CRL was
* obtained for.
*
* @param[in] ok Whether the current verification step succeeded.
* @param[in,out] ctx Certificate store context of the verification.
* @return 1 to continue the verification, 0 to fail it.
*/
static int
nc_tls_verify_crl_cb(int ok, X509_STORE_CTX *ctx)
{
char *subject;
int depth;

if (ok || (X509_STORE_CTX_get_error(ctx) != X509_V_ERR_UNABLE_TO_GET_CRL)) {
return ok;
}

subject = nc_server_tls_get_subject_wrap(X509_STORE_CTX_get_current_cert(ctx));
depth = X509_STORE_CTX_get_error_depth(ctx);
if (depth) {
/* publishing a CRL is optional for a CA, so this is an expected static property of the deployed PKI */
VRB(NULL, "No CRL available for CA certificate \"%s\" (depth %d).", subject ? subject : "", depth);
} else {
/* either we failed to download it or there was another cert in the chain that had a CRL dist point,
* either way, not knowing the revocation status is a high risk for the peer certificate, so we log a warning */
WRN(NULL, "No CRL available for the peer certificate \"%s\", its revocation status is unknown.",
subject ? subject : "");
}
free(subject);

/* clear the error so that it is not reported once the verification finishes */
X509_STORE_CTX_set_error(ctx, X509_V_OK);
return 1;
}

int
nc_tls_verify_cert_chain_crl_wrap(void *cert_chain, void *cert_store, void *UNUSED(crl_store))
{
Expand Down Expand Up @@ -892,8 +933,10 @@ nc_tls_verify_cert_chain_crl_wrap(void *cert_chain, void *cert_store, void *UNUS
untrusted = NULL;
}

/* enable CRL checks for all certificates in the chain */
/* enable CRL checks for all the certificates in the chain, certificates without an available
* CRL are tolerated by the callback */
X509_STORE_CTX_set_flags(verify_ctx, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
X509_STORE_CTX_set_verify_cb(verify_ctx, nc_tls_verify_crl_cb);

ret = X509_verify_cert(verify_ctx);
if (ret != 1) {
Expand Down
12 changes: 8 additions & 4 deletions src/session_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -780,13 +780,17 @@ void *nc_tls_get_peer_cert_chain_wrap(void *tls_session);
/**
* @brief Verify a certificate chain against CRLs.
*
* For OpenSSL, uses X509_STORE_CTX with X509_V_FLAG_CRL_CHECK |
* X509_V_FLAG_CRL_CHECK_ALL to verify the chain including CRL signature checks.
* Every certificate in the chain that a CRL was obtained for is checked, including its
* CRL signature. Certificates with no CRL available are left unchecked, since publishing
* a CRL is optional for a CA.
*
* For OpenSSL, uses X509_STORE_CTX with X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL
* and a verification callback tolerating the certificates with no CRL available.
* cert_store must contain both CAs and CRLs. crl_store is unused.
*
* For MbedTLS, uses mbedtls_x509_crt_verify with the CRL store, which verifies
* CRL signatures as part of chain verification. Both cert_store (CA certs)
* and crl_store (CRLs) are required.
* CRL signatures as part of chain verification and skips the CAs with no CRL on its own.
* Both cert_store (CA certs) and crl_store (CRLs) are required.
*
* @param[in] cert_chain Peer's certificate chain.
* @param[in] cert_store Certificate store (OpenSSL: contains CAs + CRLs, MbedTLS: CA certs).
Expand Down
Loading