1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-08 14:02:17 +03:00

16 Commits

Author SHA1 Message Date
Vladislav Vaintroub
8804593283 CONC-767 Improve SSL verification performance on Windows
Fixes slow SSL handshakes in network-restricted environments. On Windows,
the verification process uses the CertGetCertificateChain API, which
may attempt to refresh the CA list or fetch CRLs/OCSP data from the
network. This can trigger slow network lookups when no CA or CRL is
explicitly specified.

This patch disables these unnecessary network calls by using flags
like CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL to prevent external requests
during certificate chain validation. Additionally, it applies
Microsoft-recommended optimizations to speed up certificate handling
and avoid delays in SSL handshakes.

Also, unless explicitly requested(via ca_cert or crl_file or similar),
do not bother to verify name, CA or CRL for local connections. It saves
time. The failures in verification were previously discarded anyway.
2025-04-17 19:55:17 +02:00
Vladislav Vaintroub
73823d9b56 Merge branch '3.3' into 3.4 2024-11-07 08:47:37 +01:00
Vladislav Vaintroub
76564675fc Merge 3.1 into 3.3 2024-11-07 08:47:12 +01:00
Vladislav Vaintroub
b1f1267805 CONC-527 post-fix.
Add fallback if CryptAcquireContext fails with ERROR_ACCESS_DENIED,
as seen in Jenkins CI.

The fallback, also suggested by https://stackoverflow.com/a/14053718/547065,
is to retry with machine-wide key container, if user-specific fails.
2024-11-07 08:30:59 +01:00
Georg Richter
4a157ffbb5 Merge branch '3.3' into 3.4 2024-08-31 07:37:31 +02:00
Sergei Golubchik
0f3a41ec77 TLS post-fixes
* fix comments
* reorder errors to put hard errors on top
* report errors from openssl
* don't overwrite errors in C/C
* pass correct flags to gnutls_x509_crt_check_hostname2()
* use the same define name everywhere consistently
* don't recalculate fingerprint in openssl unnecessary
* misc
2024-08-03 16:37:57 +02:00
Vladislav Vaintroub
1e8e1f4f38 Fix "set but not used" warnings. 2024-07-31 20:48:44 +02:00
Vladislav Vaintroub
72116a30ab Merge branch '3.1' into 3.3 2024-07-29 11:53:15 +02:00
Vladislav Vaintroub
6a67a34f47 CONC-527 "SEC_E_ALGORITHM_MISMATCH" connecting Windows client to Ubuntu
The bug happens only when connecting with SSL with client certificates.

Apparently if client certificates are used in TLS handshake,
private keys for cert should be loaded into named persistent
container.This is because AcquireCredentialsHandle is done partically
out-of-process in lsass.exe, and lsass wants to read private keys from disk

See discussion in https://github.com/dotnet/runtime/issues/23749

Schannel has legacy behavior for ephemeral keys, not involving lsass,
and this is why it worked for us so far, however there are limitations.

It appears to only use rsa_sha1 for signature verification, and newer
OpenSSL no longer allows SHA1 for it, and this ends up in
"algorithm mismatch" message from schannel.

The above is just my understanding of how it works, because there is no
real documentation, the conclusion is based on discussion in
https://github.com/dotnet/runtime/issues/23749

The fix:
So storing the key in persistent named container evidently fixes it,
and this is what is done in this patch. Care is takes to destroy
key container after key is no longer needed, to
avoid filling  %AppData%\Roaming\Microsoft\Crypto\RSA with tiny encrypted
key files. Thus the "persistency window" of the key in container on disk
is only for duration of AcquireCredentialsHandle
2024-07-28 03:46:50 +02:00
Georg Richter
1287c901dc TLS/SSL changes (major rework)
Peer certificate validation:

Since version 3.4 peer certificate verification is enabled by default.
It can be disabled via `mysql_optionsv`, using option
MYSQL_OPT_SSL_VERIFY_SERVER_CERT:

    my_bool verify= 0;
    mysql_options(mariadb, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &verify);

Self signed certificates

If the client obtained a self signed peer certificate from MariaDB server
the verification will fail, with the following exceptions:

* If the connection between client and server is considered to be secure:, e.g.
  * a unix_socket is used for client server communication
  * hostname is localhost (Windows operating system), 127.0.0.1 or ::1
* a specified fingerprint matches the fingerprint of the peer certificate (see below)
* a client can verify the certificate using account password, it's possible if
  * account has a password
  * authentication plugin is "secure without TLS", that is, one of
    mysql_native_password, ed25519 or parsec.

Fingerprint verification of the peer certificate

A fingerprint is a cryptographic hash (SHA-256, SHA-384 or SHA-512) of the peer
certificate's binary data. Even if the fingerprint matches, an expired or
revoked certificate will not be accepted.

For security reasons support for MD5 and SHA1 has been removed.

Technical details:
==================

- Peer certificate verification call was removed from ma_tls_connect, instead it
  will be called directly after the handshake succeeded (my_auth.c)

- mysql->net.tls_self_signed_error was replaced by mysql->net.tls_verify_status which
  contains the result of the peer certfificate verification:

  The verification status can be obtained with mariadb_get_infov using new parameter
  MARIADB_TLS_VERIFY_STATUS.

  unsigned int tls_verify_status;
  mariadb_get_infov(mysql, MARIADB_TLS_VERIFY_STATUS, &tls_verify_status);

  The result is a combination of the following flags:

  MARIADB_TLS_VERIFY_OK                  0
  MARIADB_TLS_VERIFY_TRUST               1
  MARIADB_TLS_VERIFY_HOST                2
  MARIADB_TLS_VERIFY_PERIOD              4
  MARIADB_TLS_VERIFY_FINGERPRINT         8
  MARIADB_TLS_VERIFY_REVOKED            16
  MARIADB_TLS_VERIFY_UNKNOWN            32

- GnuTLS peer certificate verification callback was removed and replaced by
  gnutls_verify_peers2() api function, so the peer certificate validation
  will happen after handshake.

- OpenSSL implementation will no longer use SSL_verify_result to check the
  validity of the peer certificate. Instead a callback function will be called
  during the handshake, which collects all certificate validation errors.

- If the peer certificate is not trusted, hostname verification will be
  skipped.

- Testing
  Added new test tls, which implements a python based dummy server, which allows
  to set different certificates and TLS options. Please note. that tests are
  expected to fail, since the server doesn't support further steps like user
  authentication etc. after the handshake. Prerequisite for running the tls test
  is Python3.
2024-07-16 13:12:26 +02:00
Vladislav Vaintroub
4692e9cec1 CONC-645 : fix build with clang (v16), clang-cl(v16), and mingw-gcc(v12).
schannel_certs.c - conflicting headers, include winsock2.h before windows.h,

strerror_r is now defined also with mingw

do not build mariadb_config on Windows, getopt.h is missing
2023-09-22 00:59:48 +02:00
Vladislav Vaintroub
802ce584a2 CONC-555 appverifier error in schannel_free_cert_context
It looks like CertFreeCertificateContext() would try to access
freed memory.

Fix it by using CERT_STORE_NO_CRYPT_RELEASE_FLAG when setting private key
in certificate, i.e avoid releasing the crypto provider when certificate
is freed.

Note:
My attempts to fix with less code , i.e just omit CryptReleaseContext(),
failed, there was a small memory leak left after freeing each SSL
connection.
2021-06-14 22:45:19 +02:00
Georg Richter
820faff627 codespell fixes, removed MSDOS preprocessor macros 2020-11-26 09:07:17 +01:00
Vladislav Vaintroub
777460c226 Fix C11 conformance
Ellipsis in variadic macro requires at least 1 argument
2020-11-12 23:24:19 +00:00
Vladislav Vaintroub
2efc52b5b7 Fix clang-tidy warnings.
simplify error handling in schannel_certs.c
2019-12-09 00:22:46 +01:00
Vladislav Vaintroub
63df45ce3d CONC-447 ERROR 2026 (HY000): SSL connection error: Certificate signature check failed
Implement proper verification for server certificate chain,
with refactoring of the certificate stuff.

If custom CA and CRL certs are given, load them into in-memory store, and
use CertVerifyCertificateChainPolicy() to verify the certificate chain.

There are minor errors fixed, such as
- now there is a support for private keys encoded as BEGIN/END PRIVATE KEY
in PEM, instead of only BEGIN/END RSA PRIVATE KEY
- memory leak around CryptAcquireContext() is fixed i.e when client loads
private key, it previously did never released it, not even when connection
ended.

The handling of certificates moved into schannel_certs.c from various places
2019-12-08 18:07:48 +01:00