summaryrefslogtreecommitdiffstats
path: root/vio
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
commita2a2e32c02643a0cec111511220227703fda1cd5 (patch)
tree69cc2b631234c2a8e026b9cd4d72676c61c594df /vio
parentReleasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff)
downloadmariadb-a2a2e32c02643a0cec111511220227703fda1cd5.tar.xz
mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.zip
Merging upstream version 1:11.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vio')
-rw-r--r--vio/viosslfactories.c243
1 files changed, 129 insertions, 114 deletions
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 289c28d4..8e76c814 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -20,10 +20,15 @@
#ifdef HAVE_OPENSSL
#include <openssl/dh.h>
#include <openssl/bn.h>
+#include <openssl/x509.h>
static my_bool ssl_algorithms_added = FALSE;
static my_bool ssl_error_strings_loaded= FALSE;
+#ifndef X509_VERSION_3
+#define X509_VERSION_3 2
+#endif
+
/* the function below was generated with "openssl dhparam -2 -C 2048" */
#ifndef HAVE_WOLFSSL
static
@@ -95,6 +100,61 @@ sslGetErrString(enum enum_ssl_init_error e)
return ssl_error_string[e];
}
+static EVP_PKEY *vio_keygen()
+{
+ EVP_PKEY_CTX *ctx;
+ EVP_PKEY *pkey = NULL;
+
+ if (!(ctx= EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)))
+ return NULL;
+
+ if (EVP_PKEY_keygen_init(ctx) <= 0)
+ goto end;
+
+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 4096) <= 0)
+ goto end;
+
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+ pkey= NULL; /* just in case */
+
+end:
+ EVP_PKEY_CTX_free(ctx);
+ return pkey;
+}
+
+static X509 *vio_gencert(EVP_PKEY *pkey)
+{
+ X509 *x;
+ X509_NAME *name;
+
+ if (!(x= X509_new()))
+ goto err;
+
+ if (!X509_set_version(x, X509_VERSION_3))
+ goto err;
+ if (!(name= X509_get_subject_name(x)))
+ goto err;
+ if (!X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+ (uchar*)STRING_WITH_LEN("MariaDB Server"), -1, 0))
+ goto err;
+ if (!X509_set_issuer_name(x, name))
+ goto err;
+ if (!X509_gmtime_adj(X509_get_notBefore(x), 0))
+ goto err;
+ if (!X509_gmtime_adj(X509_get_notAfter(x), 60*60*24*365*10))
+ goto err;
+ if (!X509_set_pubkey(x, pkey))
+ goto err;
+ if (!X509_sign(x, pkey, EVP_sha256()))
+ goto err;
+
+ return x;
+
+err:
+ X509_free(x);
+ return NULL;
+}
+
static int
vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
my_bool is_client, enum enum_ssl_init_error* error)
@@ -103,14 +163,38 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
DBUG_PRINT("enter", ("ctx: %p cert_file: %s key_file: %s",
ctx, cert_file, key_file));
- if (!cert_file && key_file)
+ if (!cert_file && !key_file)
+ {
+ if (!is_client)
+ {
+ EVP_PKEY *pkey;
+ X509 *x509;
+ if (!(pkey= vio_keygen()) || SSL_CTX_use_PrivateKey(ctx, pkey) < 1)
+ {
+ *error= SSL_INITERR_KEY;
+ fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error));
+ DBUG_RETURN(1);
+ }
+
+ if (!(x509= vio_gencert(pkey)) || SSL_CTX_use_certificate(ctx, x509) < 1)
+ {
+ *error= SSL_INITERR_CERT;
+ fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error));
+ DBUG_RETURN(1);
+ }
+ EVP_PKEY_free(pkey); /* decrement refcnt */
+ X509_free(x509); /* ditto */
+ }
+ DBUG_RETURN(0);
+ }
+
+ /* cert and key can be combined in one file */
+ if (!cert_file)
cert_file= key_file;
-
- if (!key_file && cert_file)
+ else if (!key_file)
key_file= cert_file;
- if (cert_file &&
- SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0)
+ if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0)
{
*error= SSL_INITERR_CERT;
DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file));
@@ -121,8 +205,7 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
DBUG_RETURN(1);
}
- if (key_file &&
- SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
+ if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
{
*error= SSL_INITERR_KEY;
DBUG_PRINT("error", ("%s from file '%s'", sslGetErrString(*error), key_file));
@@ -137,7 +220,7 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
If certificate is used check if private key matches.
Note, that server side has to use certificate.
*/
- if ((cert_file != NULL || !is_client) && !SSL_CTX_check_private_key(ctx))
+ if (!SSL_CTX_check_private_key(ctx))
{
*error= SSL_INITERR_NOMATCH;
DBUG_PRINT("error", ("%s",sslGetErrString(*error)));
@@ -221,52 +304,38 @@ static long vio_tls_protocol_options(ulonglong tls_version)
return (disabled_tls_protocols | disabled_ssl_protocols);
}
+/*
+ If some optional parameters indicate empty strings, then
+ for compatibility with SSL libraries, replace them with NULL,
+ otherwise these libraries will try to open files with an empty
+ name, etc., and they will return an error code instead of performing
+ the necessary operations:
+*/
+#define fix_value(X) if (X && !X[0]) X= NULL
+
/************************ VioSSLFd **********************************/
static struct st_VioSSLFd *
-new_VioSSLFd(const char *key_file, const char *cert_file,
- const char *ca_file, const char *ca_path,
- const char *cipher, my_bool is_client_method,
- enum enum_ssl_init_error *error,
- const char *crl_file, const char *crl_path, ulonglong tls_version)
+new_VioSSLFd(const char *key_file, const char *cert_file, const char *ca_file,
+ const char *ca_path, const char *cipher, my_bool is_client_method,
+ enum enum_ssl_init_error *error, const char *crl_file,
+ const char *crl_path, ulonglong tls_version)
{
struct st_VioSSLFd *ssl_fd;
long ssl_ctx_options;
DBUG_ENTER("new_VioSSLFd");
- /*
- If some optional parameters indicate empty strings, then
- for compatibility with SSL libraries, replace them with NULL,
- otherwise these libraries will try to open files with an empty
- name, etc., and they will return an error code instead performing
- the necessary operations:
- */
- if (ca_file && !ca_file[0])
- {
- ca_file = NULL;
- }
- if (ca_path && !ca_path[0])
- {
- ca_path = NULL;
- }
- if (crl_file && !crl_file[0])
- {
- crl_file = NULL;
- }
- if (crl_path && !crl_path[0])
- {
- crl_path = NULL;
- }
+ fix_value(key_file);
+ fix_value(cert_file);
+ fix_value(ca_file);
+ fix_value(ca_path);
+ fix_value(crl_file);
+ fix_value(crl_path);
+ fix_value(cipher);
DBUG_PRINT("enter",
("key_file: '%s' cert_file: '%s' ca_file: '%s' ca_path: '%s' "
- "cipher: '%s' crl_file: '%s' crl_path: '%s'",
- key_file ? key_file : "NULL",
- cert_file ? cert_file : "NULL",
- ca_file ? ca_file : "NULL",
- ca_path ? ca_path : "NULL",
- cipher ? cipher : "NULL",
- crl_file ? crl_file : "NULL",
- crl_path ? crl_path : "NULL"));
+ "cipher: '%s' crl_file: '%s' crl_path: '%s'", key_file,
+ cert_file, ca_file, ca_path, cipher, crl_file, crl_path));
vio_check_ssl_init();
@@ -395,6 +464,10 @@ err0:
DBUG_RETURN(0);
}
+int always_ok(int preverify, X509_STORE_CTX* store)
+{
+ return 1;
+}
/************************ VioSSLConnectorFd **********************************/
struct st_VioSSLFd *
@@ -404,55 +477,23 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
const char *crl_file, const char *crl_path)
{
struct st_VioSSLFd *ssl_fd;
- int verify= SSL_VERIFY_PEER;
-
- if (ca_file && ! ca_file[0]) ca_file = NULL;
- if (ca_path && ! ca_path[0]) ca_path = NULL;
- if (crl_file && ! crl_file[0]) crl_file = NULL;
- if (crl_path && ! crl_path[0]) crl_path = NULL;
-
- /*
- If some optional parameters indicate empty strings, then
- for compatibility with SSL libraries, replace them with NULL,
- otherwise these libraries will try to open files with an empty
- name, etc., and they will return an error code instead performing
- the necessary operations:
- */
- if (ca_file && !ca_file[0])
- {
- ca_file = NULL;
- }
- if (ca_path && !ca_path[0])
- {
- ca_path = NULL;
- }
- if (crl_file && !crl_file[0])
- {
- crl_file = NULL;
- }
- if (crl_path && !crl_path[0])
- {
- crl_path = NULL;
- }
+ int (*cb)(int, X509_STORE_CTX *) = NULL;
/*
- Turn off verification of servers certificate if both
- ca_file and ca_path is set to NULL
+ Don't abort when the certificate cannot be verified if neither
+ ca_file nor ca_path were set.
*/
- if (ca_file == 0 && ca_path == 0)
- verify= SSL_VERIFY_NONE;
+ if ((ca_file == 0 || ca_file[0] == 0) && (ca_path == 0 || ca_path[0] == 0))
+ cb= always_ok;
- if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
- ca_path, cipher, TRUE, error,
- crl_file, crl_path, 0)))
+ /* Init the VioSSLFd as a "connector" ie. the client side */
+ if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher,
+ TRUE, error, crl_file, crl_path, 0)))
{
return 0;
}
- /* Init the VioSSLFd as a "connector" ie. the client side */
-
- SSL_CTX_set_verify(ssl_fd->ssl_context, verify, NULL);
-
+ SSL_CTX_set_verify(ssl_fd->ssl_context, SSL_VERIFY_PEER, cb);
return ssl_fd;
}
@@ -468,38 +509,12 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
struct st_VioSSLFd *ssl_fd;
int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
- /*
- If some optional parameters indicate empty strings, then
- for compatibility with SSL libraries, replace them with NULL,
- otherwise these libraries will try to open files with an empty
- name, etc., and they will return an error code instead performing
- the necessary operations:
- */
- if (ca_file && !ca_file[0])
- {
- ca_file = NULL;
- }
- if (ca_path && !ca_path[0])
- {
- ca_path = NULL;
- }
- if (crl_file && !crl_file[0])
- {
- crl_file = NULL;
- }
- if (crl_path && !crl_path[0])
- {
- crl_path = NULL;
- }
-
- if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
- ca_path, cipher, FALSE, error,
- crl_file, crl_path, tls_version)))
+ /* Init the the VioSSLFd as a "acceptor" ie. the server side */
+ if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher,
+ FALSE, error, crl_file, crl_path, tls_version)))
{
return 0;
}
- /* Init the the VioSSLFd as a "acceptor" ie. the server side */
-
/* Set max number of cached sessions, returns the previous size */
SSL_CTX_sess_set_cache_size(ssl_fd->ssl_context, 128);