MySQL 8.4.1
Source Code Documentation
ssl_operation.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2021, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef ROUTER_SRC_HTTP_SRC_TLS_SSL_OPERATION_H_
27#define ROUTER_SRC_HTTP_SRC_TLS_SSL_OPERATION_H_
28
29#include <openssl/bio.h>
30#include <openssl/err.h>
31#include <openssl/ssl.h>
32
33// OpenSSL version hex format: 0xMNN00PPSL
34#define NET_TLS_USE_BACKWARD_COMPATIBLE_OPENSSL 0x10100000L
35
36namespace net {
37namespace tls {
38
39class Operation {
40 public:
42
43 public:
44 virtual ~Operation() = default;
45
46 protected:
48 public:
49 AnalyzeOperation(BIO *bio, SSL *ssl)
50 : bio_{bio}, ssl_{ssl}, pending_{BIO_pending(bio)} {
51 ERR_clear_error();
52 }
53
54 Result check_ssl_result(int ssl_result) {
55 auto pending = BIO_pending(bio_);
56
57 auto error_cause = SSL_get_error(ssl_, ssl_result);
58 Result op_result = ok;
59
60 if (ssl_result <= 0) {
61 switch (error_cause) {
62 case SSL_ERROR_WANT_READ:
63 op_result = want_read;
64 break;
65
66 case SSL_ERROR_WANT_WRITE:
67 op_result = want_write;
68 break;
69
70 case SSL_ERROR_ZERO_RETURN:
71 return close;
72
73 case SSL_ERROR_SYSCALL:
74 if (pending > pending_) return want_write;
75 return fatal;
76
77 case SSL_ERROR_SSL:
78 return fatal;
79
80 default:
81 return fatal;
82 }
83 }
84
85 if (pending) {
86 op_result = want_write;
87 }
88
89 return op_result;
90 }
91
92 BIO *bio_;
93 SSL *ssl_;
95 };
96};
97
99 public:
100 static bool is_read_operation() { return true; }
101
102#if OPENSSL_VERSION_NUMBER >= NET_TLS_USE_BACKWARD_COMPATIBLE_OPENSSL
103 static int read_ex(SSL *ssl, void *buf, size_t num,
104 size_t *out_number_of_bytes_io) {
105 return SSL_read_ex(ssl, buf, num, out_number_of_bytes_io);
106 }
107#else
108 static int read_ex(SSL *ssl, void *buf, size_t num,
109 size_t *out_number_of_bytes_io) {
110 *out_number_of_bytes_io = 0;
111 auto result = SSL_read(ssl, buf, num);
112 if (result > 0) *out_number_of_bytes_io = result;
113 return result;
114 }
115#endif
116
117 static Result op(BIO *bio, SSL *ssl, void *buffer, const size_t buffer_size,
118 size_t *out_number_of_bytes_io) {
120 bio,
121 ssl,
122 };
123
124 if (!buffer_size) return ok;
125
126 return op.check_ssl_result(
127 read_ex(ssl, buffer, buffer_size, out_number_of_bytes_io));
128 }
129};
130
132 public:
133#if OPENSSL_VERSION_NUMBER >= NET_TLS_USE_BACKWARD_COMPATIBLE_OPENSSL
134 static int write_ex(SSL *ssl, const void *buf, size_t num,
135 size_t *out_number_of_bytes_io) {
136 return SSL_write_ex(ssl, buf, num, out_number_of_bytes_io);
137 }
138#else
139 static int write_ex(SSL *ssl, const void *buf, size_t num,
140 size_t *out_number_of_bytes_io) {
141 *out_number_of_bytes_io = 0;
142 auto result = SSL_write(ssl, buf, num);
143 if (result > 0) *out_number_of_bytes_io = result;
144 return result;
145 }
146#endif
147
148 static bool is_read_operation() { return false; }
149 static Result op(BIO *bio, SSL *ssl, const void *buffer,
150 const size_t buffer_size, size_t *out_number_of_bytes_io) {
152 bio,
153 ssl,
154 };
155
156 if (!buffer_size) return ok;
157
158 return op.check_ssl_result(
159 write_ex(ssl, buffer, buffer_size, out_number_of_bytes_io));
160 }
161};
162
163} // namespace tls
164} // namespace net
165
166#endif // ROUTER_SRC_HTTP_SRC_TLS_SSL_OPERATION_H_
Definition: ssl_operation.h:47
Result check_ssl_result(int ssl_result)
Definition: ssl_operation.h:54
AnalyzeOperation(BIO *bio, SSL *ssl)
Definition: ssl_operation.h:49
BIO * bio_
Definition: ssl_operation.h:92
int pending_
Definition: ssl_operation.h:94
SSL * ssl_
Definition: ssl_operation.h:93
Definition: ssl_operation.h:39
Result
Definition: ssl_operation.h:41
@ want_read
Definition: ssl_operation.h:41
@ fatal
Definition: ssl_operation.h:41
@ want_write
Definition: ssl_operation.h:41
@ ok
Definition: ssl_operation.h:41
@ close
Definition: ssl_operation.h:41
virtual ~Operation()=default
Definition: ssl_operation.h:98
static int read_ex(SSL *ssl, void *buf, size_t num, size_t *out_number_of_bytes_io)
Definition: ssl_operation.h:108
static Result op(BIO *bio, SSL *ssl, void *buffer, const size_t buffer_size, size_t *out_number_of_bytes_io)
Definition: ssl_operation.h:117
static bool is_read_operation()
Definition: ssl_operation.h:100
Definition: ssl_operation.h:131
static bool is_read_operation()
Definition: ssl_operation.h:148
static Result op(BIO *bio, SSL *ssl, const void *buffer, const size_t buffer_size, size_t *out_number_of_bytes_io)
Definition: ssl_operation.h:149
static int write_ex(SSL *ssl, const void *buf, size_t num, size_t *out_number_of_bytes_io)
Definition: ssl_operation.h:139
Definition: buf0block_hint.cc:30
constexpr value_type ssl
Definition: classic_protocol_constants.h:49
Definition: buffer.h:45
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
size_t buffer_size(const ConstBufferSequence &buffers) noexcept
Definition: buffer.h:313
Definition: tls_keylog_dumper.h:32
struct result result
Definition: result.h:34
Definition: result.h:30