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

66 Commits

Author SHA1 Message Date
Georg Richter
b3adb24128 Merge branch '3.3' into 3.4 2025-06-07 16:50:38 +02:00
Georg Richter
aebe28b8eb CONC-778: TLSv1.3 support for Windows Server 2022
Windows Server 2022 uses version number 10.0.20348, which is less than 10.0.22000.
Therefore, instead of checking for build numbers >= 22000 (which would exclude Server 2022),
we must check for build numbers >= 20348 to correctly include both Windows Server 2022
and Windows 11.

This is safe because TLSv1.3 was first supported in:
- Windows 11 (starting with build 22000)
- Windows Server 2022 (starting with build 20348)

Earlier versions did not support TLSv1.3:
- Windows 10 (up to build 19044)
- Windows Server 2019 (latest build 17763)
2025-06-07 15:32:44 +02:00
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
58d773da30 Schannel - parse TLSv1.0, but ignore attempt to use it
This is apparently what server test suite wants in tls_version.test
2024-10-30 08:39:57 +01:00
Georg Richter
968b5f0aa2 Fix for CONC-731: wrong error message (incorrect fp)
- moved fingerprint verification to ma_tls.c
- don't verify cert again if fingerprint check
  succeeded.
- Disable self signed check in fingerprint tests
  (Schannel only).
2024-09-24 12:08:42 +02:00
Georg Richter
57f38cf87f Save the result of peer certificate verification
Since the MARIADB_TLS_VERIFY_TRUST flag might be cleared in my_auth,
we store the original result of peer certificate verification in
mysql->extension->tls_validation.
This value can be obtained via mariadb_get_infov API function
using option MARIADB_TLS_VERIFY_STATUS.
2024-08-31 07:53:46 +02:00
Georg Richter
4a157ffbb5 Merge branch '3.3' into 3.4 2024-08-31 07:37:31 +02:00
Georg Richter
c5ce23d340 Fix compiler warnings (schannel.c) 2024-08-30 07:39:46 +02:00
Vladislav Vaintroub
3ceb310ebe CONC-567 Schannel : support TLSv1.3
Use SCH_CREDENTIAL structure, to support TLSv1.3
Allow TLSv1.3 starting with Windows 11 / Server 2022, which are
first Windows releases to officially support latest TLS version
2024-07-31 20:48:34 +02:00
Vladislav Vaintroub
d15c73859c CONC-567 Schannel - handle SEC_I_RENEGOTIATE, prepare for TLSv1.3
There is no real renegotiation in TLSv1.3 protocol, so it is
some internal schannel thing, that makes DecryptMessage() to return
SEC_I_RENEGOTIATE, to replay a handshake step.

This pops up when TLSv1.3 is enabled.
2024-07-31 20:48:08 +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
c5d2a0ebb3 TLS (schannel) fixes:
- don't verify fingerprint twice
- pci->dwVersion (certificate version) needs to be increased by 1
- use MARIADB_TLS_VERIFY_UNKNOWN for unknown tls verification errors
2024-07-18 05:44: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
Georg Richter
71fa44cff0 CONC-698: certificate info is read on every connect
Part 1: Fix for OpenSSL and Schannel
2024-06-20 08:34:19 +02:00
Georg Richter
19dffea4dc CONC-692: Provide X509 peer certificate information
Added a new structure MARIADB_X509_INFO, which
contains information about servers certificate.
The information can be obtained via mysql_get_infov API
function:

MARIADB_X509_INFO *info;
mariadb_get_infov(mysql, MARIADB_TLS_PEER_CERT_INFO, &info);
2024-04-24 11:21:28 +02:00
Georg Richter
fe411bf336 CONC-403:
Remove support of TLSv1.0 protocol
2024-02-20 09:52:07 +01:00
Sergei Golubchik
8dffd56936 MDEV-31857 enable MYSQL_OPT_SSL_VERIFY_SERVER_CERT by default
because the default value of every option is 0
(option and option.extension are bzero-ed to reset),
tls_verify_server_cert was renamed to tls_allow_invalid_server_cert
with the default value of 0, "do not allow".

API didn't change, it's still MYSQL_OPT_SSL_VERIFY_SERVER_CERT
2024-02-04 22:17:25 +01:00
Georg Richter
9aa15e72a7 TLS fingerprint
Beside SHA1 fingerprint hash, Connector/C now also supports
SHA224 (OpenSSL and GnuTLS only), SHA256, SHA384 and SHA512
fingerprint hashes.
2024-02-04 22:17:22 +01:00
Georg Richter
45feebb99d Remove server certification verification
Since the server certification option is used by client
only, there is no need to have this flag in server and or
client capabilities. The server itself validates client
certificate depending on the user definition.
2023-07-13 09:30:33 +02:00
Georg Richter
12722e3131 Error message fix:
Since TLS errors might happen not only when connecting and SSL protocol
is not longer used, errormessage for CR_SSL_CONNECTION_ERROR was replaced
by TLS/SSL error.
2022-07-27 14:52:20 +02:00
Georg Richter
9a572bc548 Fix for CONC-604 and CONC-605:
This patch fixes a crash when reconnectiong via TLS.
2022-07-18 11:41:46 +02:00
Georg Richter
13bcf7cfdf Fix for CONC-539
Added cipher suites ECDHE-RSA-AES128-SHA256 (0xC027) and
ECDHE-RSA-AES256-SHA384 (0xC028) to the cipher map which maps
cipher suite names to the corresponding algorithm ids.

Since this list is still incomplete, and additional list containing
the cipher suite ids and openssl cipher suite names was added. This
list will be used now to detect the cipher suite for the current
connection.
2021-04-01 07:15:29 +02:00
Vladislav Vaintroub
ce011210d1 small cleanups
remove MSVC specific #pragma comment(lib)
TARGET_LINK_LIBRARIES is good enough
2020-05-27 20:32:56 +02: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
Vladislav Vaintroub
c8833751cf CONC-446 For Schannel errors, provide better errors
Print error symbol (e.g S"EC_E_ILLEGAL_MESSAGE") in the error message
for some schannel errors, in addition to error message

Print error code for all errors coming from schannel.

Fix some whitespace.
2019-11-29 11:19:48 +01:00
Georg Richter
8983406ade Merge commit 'd4a0a384459e3a6645ad4df46db18a5d2dd4c780' into 3.1 2019-06-14 13:36:07 +02:00
Georg Richter
78e857e3af Removed unused call to QueryContextAttributes with connection info. 2019-06-03 11:03:57 +02:00
Georg Richter
546b07a3f0 Merge commit 'b0411b731f5d61df38fe3f783437df13526774f2' into 3.1 2019-06-02 13:46:16 +02:00
Georg Richter
b0411b731f CONC-386:
Added support for pem files which contain certificate and private key.
In case the file will contain more than one certificate or key, the first
certificate or key found will be used.
2019-06-02 13:39:27 +02:00
Vladislav Vaintroub
212f9b39b6 CONC-412 - Allow TLS1.2 in Schannel 2019-05-22 15:14:26 +02:00
Vladislav Vaintroub
db1a1a1d31 more clang fixes 2018-02-12 09:29:27 +00:00
Vladislav Vaintroub
935c33b690 Fix Windows size_t warnings. 2018-01-12 18:19:19 +00:00
Vladislav Vaintroub
11edece5c4 Partial revert of abf4bf8024 (provide details
of ssl version).

We do not need to know the version of schannel.dll. Its version is always
the same as OS version. So do not add extra file IOs to the client
library.
2017-11-13 14:07:22 +00:00
Georg Richter
b241f8995f MDEV-14101: tls-version
Client part of MDEV-14101: Add support for tls-version, via
mysql_options(mysql, MARIADB_OPT_TLS_VERSION, value)
Accepted values are "TLSv1.1", "TLSv1.2" and "TLSv1.3".

Fixed testcase openssl_1 for schannel
2017-10-23 11:09:54 +02:00
Georg Richter
abf4bf8024 Provide details about TLS/SSL library in use
When calling mariadb_get_infov with option MARIADB_TLS_LIBRARY
the functioni now returns the correct version number and name
of the tls/ssl library in use.
2017-10-17 15:57:42 +02:00
Georg Richter
3b297e08c9 Revert "MDEV-14027: Determine TLS/SSL library version"
This reverts commit 7b02cbb721.
2017-10-15 09:30:24 +02:00
Georg Richter
7b02cbb721 MDEV-14027: Determine TLS/SSL library version 2017-10-15 06:07:54 +02:00
Georg Richter
02f57a9c14 Fix for CONC-276: client library crashes on Windows after TLS reconnect:
The connection pointer mysql is now no longer part (and doesn't need to be updated) of schannel security context, since it can be obtained directly from tls container.
2017-08-24 18:09:50 +02:00
Vladislav Vaintroub
06d2490371 MDEV-11159 Add support for sending proxy protocol header 2017-06-13 18:19:07 +00:00
Georg Richter
25a97fcd77 Fix for CONC-250: Added support for wildcards and SAN 2017-05-08 18:47:57 +02:00
Vladislav Vaintroub
ba22ae8c6d Fix schannel and other socket io bugs on Windows.
- Fix a breaking change where
SP_PROT_TLS1_2_CLIENT bit was set in Cred.grbitEnabledProtocols by default.

This makes any SSL connection to Windows server fai, because
all yassl-based servers, in all MariaDB versions would abort
a client that is trying to use TLS1.2
(This is covered MDEV-12190)

As a consequence, client on Windows would not connect to any
server on Windows. For compatibility reasons therefore, 1.2 should NOT
be used by clients by default, otherwise it will break applications
connectivity to both Oracle MySQL and MariaDB's yassl based servers.
This also holds after MDEV-12190 is fixed,  because older servers
will be used for a while.


- Cred.dwFlag was missing SCH_CRED_NO_DEFAULT_CREDS flag,
which resulted in a popup on the build servers, asking to insert
a smartcard during client SSL handshake.

Smaller bugs in schannel :
 cipher_name() was returning pointer to member of stack allocated struct

Socket IO fixes

- errno rather than WSAGetLastError() was tested on Windows in
  pvio_socket_write/pvio_socket_read.
  Fixed by using socker_errno and simplided function to avoid numerious #ifdef _WIN32

- simplified vio_set_blocking, it had a rather inefficient implementation
  setting the same flags with ioctlsocket/fcntl over and over again.
2017-03-29 16:33:16 +00:00
Georg Richter
92871e873f Fix compile failure: handshake_complete member for tls struct was added for debugging purposes but not removed in a previous commit 2017-03-23 22:17:33 +01:00
Georg Richter
4974bac88b Schannel fixes
To obtain the correct cipher suite name, we use the (undocumented) flag
  SECPKG_ATTR_CIPHER_INFO, which delivers cipher suite id and IANA cipher suite name.
  Added more cipher suites and mappings between IANA and OpenSSL cipher suite names
2017-03-23 17:04:33 +01:00
Georg Richter
8c34f69b33 Fix cipher mapping (tls 1.2 ciphers were missing) 2017-02-02 18:03:13 +01:00
Vladislav Vaintroub
93af3ae693 Simplify and fix ma_schannel_read_decrypt() to cache state
between the calls.

State can be unread buffer  from DecryptMessage (SECBUFFER_EXTRA)
or decrypted data that did not fit into callers buffer

- Fix error handling - SEC_I_RENEGOTIATE is handled as error,
we're not doing it yet. Stop reading at SEC_I_CONTEXT_EXPIRED.

- Fix buffer sizes  pased to SSPI ( so that large buffers can be read or written
"SELECT REPEAT('a', 20000)"

- Fix unchecked memcpy into the output buffer (size of the output buffer
was not checked, so it is a potential memory overrun)
2016-10-14 17:49:30 +00:00
Vladislav Vaintroub
629ec64630 Fix PVIO to return number of bytes read/written as "signed" integer
since there is a lot of checks for return code being < 0 or -1.
2016-10-13 17:42:03 +00:00
Vladislav Vaintroub
12797530d5 schannel cleanups
- use CertFreeCertificateContext() to free memory allocated by QueryContextAttributes(SECPKG_ATTR_REMOTE_CERT_CONTEXT)
- consistently use "SSL connection error: " prefix for schannel errors
2016-09-10 13:19:55 +00:00
Vladislav Vaintroub
2157642849 Cleanup/fix schannel TLS implementation
- remove global variables
- remove in memory certificate stores that cache all CRL and all CA
- verify certificate against ssl_ca and ssl_crl  specified in
connection options (not against all CRL/CA in store)
2016-09-09 20:17:30 +00:00
Georg Richter
9f88e25fd6 Compiler warning fixes 2016-09-03 12:46:50 +02:00