E-MailRelay
gssl_mbedtls.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2023 Graeme Walker <graeme_walker@users.sourceforge.net>
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 as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gssl_mbedtls.h
19///
20
21#ifndef G_SSL_MBEDTLS_H
22#define G_SSL_MBEDTLS_H
23
24#include "gdef.h"
25#include "gssl.h"
27#include <memory>
28#include <stdexcept>
29#include <vector>
30#include <map>
31
32namespace GSsl
33{
34 namespace MbedTls /// A namespace for implementing the GSsl interface using the mbedtls library.
35 {
36 class Certificate ;
37 class Rng ;
38 class Key ;
39 class Context ;
40 class Error ;
41 class SecureFile ;
42 class LibraryImp ;
43 class ProfileImp ;
44 class ProtocolImp ;
45 class DigesterImp ;
46 class Config ;
47 }
48}
49
50//| \class GSsl::MbedTls::Certificate
51/// Holds a mbedtls_x509_crt structure.
52///
54{
55public:
56 Certificate() ;
57 ~Certificate() ;
58 void load( const std::string & file ) ;
59 bool loaded() const ;
60 mbedtls_x509_crt * ptr() ;
61 mbedtls_x509_crt * ptr() const ;
62
63public:
64 Certificate( const Certificate & ) = delete ;
65 Certificate( Certificate && ) = delete ;
66 Certificate & operator=( const Certificate & ) = delete ;
67 Certificate & operator=( Certificate && ) = delete ;
68
69private:
70 bool m_loaded{false} ;
71 mbedtls_x509_crt x ;
72} ;
73
74//| \class GSsl::MbedTls::Rng
75/// Holds a mbedtls_ctr_drbg_context structure.
76///
78{
79public:
80 Rng() ;
81 ~Rng() ;
82 mbedtls_ctr_drbg_context * ptr() ;
83 mbedtls_ctr_drbg_context * ptr() const ;
84
85public:
86 Rng( const Rng & ) = delete ;
87 Rng( Rng && ) = delete ;
88 Rng & operator=( const Rng & ) = delete ;
89 Rng & operator=( Rng && ) = delete ;
90
91private:
92 mbedtls_ctr_drbg_context x ; // "counter-mode deterministic random byte generator"
93 mbedtls_entropy_context entropy ;
94} ;
95
96//| \class GSsl::MbedTls::Key
97/// Holds a mbedtls_pk_context structure.
98///
100{
101public:
102 Key() ;
103 ~Key() ;
104 void load( const std::string & file , const Rng & ) ;
105 mbedtls_pk_context * ptr() ;
106 mbedtls_pk_context * ptr() const ;
107
108public:
109 Key( const Key & ) = delete ;
110 Key( Key && ) = delete ;
111 Key & operator=( const Key & ) = delete ;
112 Key & operator=( Key && ) = delete ;
113
114private:
115 mbedtls_pk_context x ;
116} ;
117
118//| \class GSsl::MbedTls::Context
119/// Holds a mbedtls_ssl_context structure.
120///
122{
123public:
124 explicit Context( const mbedtls_ssl_config * ) ;
125 ~Context() ;
126 mbedtls_ssl_context * ptr() ;
127 mbedtls_ssl_context * ptr() const ;
128
129public:
130 Context( const Context & ) = delete ;
131 Context( Context && ) = delete ;
132 Context & operator=( const Context & ) = delete ;
133 Context & operator=( Context && ) = delete ;
134
135private:
136 mbedtls_ssl_context x ;
137} ;
138
139//| \class GSsl::MbedTls::Error
140/// An exception class for GSsl::MbedTls classes.
141///
142class GSsl::MbedTls::Error : public std::runtime_error
143{
144public:
145 explicit Error( const std::string & ) ;
146 Error( const std::string & , int rc , const std::string & more = {} ) ;
147
148private:
149 static std::string format( const std::string & , int , const std::string & ) ;
150} ;
151
152//| \class GSsl::MbedTls::SecureFile
153/// An interface for reading a sensitive file and then overwriting
154/// its contents in memory.
155///
157{
158public:
159 SecureFile( const std::string & path , bool with_counted_nul ) ;
160 ~SecureFile() ;
161 const char * p() const ;
162 const unsigned char * pu() const ;
163 unsigned char * pu() ;
164 std::size_t size() const ;
165 bool empty() const ;
166
167public:
168 SecureFile( const SecureFile & ) = delete ;
169 SecureFile( SecureFile && ) = delete ;
170 SecureFile & operator=( const SecureFile & ) = delete ;
171 SecureFile & operator=( SecureFile && ) = delete ;
172
173private:
174 static std::size_t fileSize( std::filebuf & ) ;
175 static bool fileRead( std::filebuf & , char * , std::size_t ) ;
176 static void scrub( char * , std::size_t ) noexcept ;
177 static void clear( std::vector<char> & ) noexcept ;
178
179private:
180 std::vector<char> m_buffer ;
181} ;
182
183//| \class GSsl::MbedTls::Config
184/// Holds protocol version information, etc.
185///
187{
188public:
189 explicit Config( G::StringArray & config ) ;
190 int min_() const noexcept ;
191 int max_() const noexcept ;
192 bool noverify() const noexcept ;
193 bool clientnoverify() const noexcept ;
194 bool servernoverify() const noexcept ;
195
196private:
197 static bool consume( G::StringArray & , G::string_view ) ;
198
199private:
200 bool m_noverify ;
201 bool m_clientnoverify ;
202 bool m_servernoverify ;
203 int m_min ;
204 int m_max ;
205} ;
206
207//| \class GSsl::MbedTls::LibraryImp
208/// An implementation of the GSsl::LibraryImpBase interface for mbedtls.
209///
210class GSsl::MbedTls::LibraryImp : public LibraryImpBase
211{
212public:
213 using Rng = MbedTls::Rng ;
214
215 LibraryImp( G::StringArray & , Library::LogFn , bool verbose ) ;
216 ~LibraryImp() override ;
217 const Rng & rng() const ;
218 Library::LogFn log() const ;
219 Config config() const ;
220 static std::string credit( const std::string & , const std::string & , const std::string & ) ;
221 static std::string sid() ;
222 static std::string version() ; // eg. "1.2.3"
223
224private: // overrides
225 void addProfile( const std::string & profile_name , bool is_server_profile ,
226 const std::string & key_file , const std::string & cert_file , const std::string & ca_file ,
227 const std::string & default_peer_certificate_name , const std::string & default_peer_host_name ,
228 const std::string & profile_config ) override ;
229 bool hasProfile( const std::string & profile_name ) const override ;
230 const Profile & profile( const std::string & profile_name ) const override ;
231 std::string id() const override ;
232 G::StringArray digesters( bool ) const override ;
233 Digester digester( const std::string & , const std::string & , bool ) const override ;
234
235public:
236 LibraryImp( const LibraryImp & ) = delete ;
237 LibraryImp( LibraryImp && ) = delete ;
238 LibraryImp & operator=( const LibraryImp & ) = delete ;
239 LibraryImp & operator=( LibraryImp && ) = delete ;
240
241private:
242 static int minVersionFrom( G::StringArray & ) ;
243 static int maxVersionFrom( G::StringArray & ) ;
244
245private:
246 using Map = std::map<std::string,std::shared_ptr<ProfileImp>> ;
247 Library::LogFn m_log_fn ;
248 Config m_config ;
249 Map m_profile_map ;
250 Rng m_rng ;
251} ;
252
253//| \class GSsl::MbedTls::ProfileImp
254/// An implementation of the GSsl::Profile interface for mbedtls.
255///
256class GSsl::MbedTls::ProfileImp : public Profile
257{
258public:
259 using Key = MbedTls::Key ;
260 using Error = MbedTls::Error ;
261 using Certificate = MbedTls::Certificate ;
262
263 ProfileImp( const LibraryImp & library_imp , bool is_server , const std::string & key_file ,
264 const std::string & cert_file , const std::string & ca_file ,
265 const std::string & default_peer_certificate_name , const std::string & default_peer_host_name ,
266 const std::string & profile_config ) ;
267 ~ProfileImp() override ;
268 const mbedtls_ssl_config * config() const ;
269 mbedtls_x509_crl * crl() const ;
270 void logAt( int level_out , std::string ) const ;
271 const std::string & defaultPeerCertificateName() const ;
272 const std::string & defaultPeerHostName() const ;
273 int authmode() const ;
274
275private: // overrides
276 std::unique_ptr<ProtocolImpBase> newProtocol( const std::string & , const std::string & ) const override ;
277
278public:
279 ProfileImp( const ProfileImp & ) = delete ;
280 ProfileImp( ProfileImp && ) = delete ;
281 ProfileImp & operator=( const ProfileImp & ) = delete ;
282 ProfileImp & operator=( ProfileImp && ) = delete ;
283
284private:
285 static void onDebug( void * , int , const char * , int , const char * ) ;
286 void doDebug( int , const char * , int , const char * ) ;
287
288private:
289 const LibraryImp & m_library_imp ;
290 const std::string m_default_peer_certificate_name ;
291 const std::string m_default_peer_host_name ;
292 mbedtls_ssl_config m_config ;
293 Key m_pk ;
294 Certificate m_certificate ;
295 Certificate m_ca_list ;
296 int m_authmode ;
297} ;
298
299//| \class GSsl::MbedTls::ProtocolImp
300/// An implementation of the GSsl::ProtocolImpBase interface for mbedtls.
301///
302class GSsl::MbedTls::ProtocolImp : public ProtocolImpBase
303{
304public:
305 using Result = Protocol::Result ;
306 using Context = MbedTls::Context ;
307 using Error = MbedTls::Error ;
308
309 ProtocolImp( const ProfileImp & , const std::string & , const std::string & ) ;
310 ~ProtocolImp() override ;
311
312 static int doSend( void * , const unsigned char * , std::size_t ) ;
313 static int doRecv( void * , unsigned char * , std::size_t ) ;
314 static int doRecvTimeout( void * , unsigned char * , std::size_t , uint32_t ) ;
315 const Profile & profile() const ;
316
317private: // overrides
318 Result connect( G::ReadWrite & ) override ;
319 Result accept( G::ReadWrite & ) override ;
320 Result read( char * buffer , std::size_t buffer_size_in , ssize_t & data_size_out ) override ;
321 Result write( const char * buffer , std::size_t data_size_in , ssize_t & data_size_out ) override ;
322 Result shutdown() override ;
323 std::string peerCertificate() const override ;
324 std::string peerCertificateChain() const override ;
325 std::string protocol() const override ;
326 std::string cipher() const override ;
327 bool verified() const override ;
328
329public:
330 ProtocolImp( const ProtocolImp & ) = delete ;
331 ProtocolImp( ProtocolImp && ) = delete ;
332 ProtocolImp & operator=( const ProtocolImp & ) = delete ;
333 ProtocolImp & operator=( ProtocolImp && ) = delete ;
334
335private:
336 Result convert( const char * , int , bool more = false ) ;
337 Result handshake() ;
338 std::string getPeerCertificate() ;
339 std::string verifyResultString( int ) ;
340
341private:
342 const ProfileImp & m_profile ;
343 G::ReadWrite * m_io ;
344 Context m_ssl ;
345 std::string m_peer_certificate ;
346 std::string m_peer_certificate_chain ;
347 bool m_verified ;
348} ;
349
350//| \class GSsl::MbedTls::DigesterImp
351/// An implementation of the GSsl::DigesterImpBase interface for MbedTls.
352///
353class GSsl::MbedTls::DigesterImp : public GSsl::DigesterImpBase
354{
355public:
356 using Error = MbedTls::Error ;
357 DigesterImp( const std::string & , const std::string & , bool ) ;
358 ~DigesterImp() override ;
359
360private: // overrides
361 void add( G::string_view ) override ;
362 std::string value() override ;
363 std::string state() override ;
364 std::size_t blocksize() const noexcept override ;
365 std::size_t valuesize() const noexcept override ;
366 std::size_t statesize() const noexcept override ;
367
368public:
369 DigesterImp( const DigesterImp & ) = delete ;
370 DigesterImp( DigesterImp && ) = delete ;
371 DigesterImp & operator=( const DigesterImp & ) = delete ;
372 DigesterImp & operator=( DigesterImp && ) = delete ;
373
374private:
375 static void check_ret( int , const char * ) ;
376
377private:
378 enum class Type { Md5 , Sha1 , Sha256 } ;
379 Type m_hash_type{Type::Md5} ;
380 mbedtls_md5_context m_md5{} ;
381 mbedtls_sha1_context m_sha1{} ;
382 mbedtls_sha256_context m_sha256{} ;
383 std::size_t m_block_size{64U} ;
384 std::size_t m_value_size{16U} ;
385 std::size_t m_state_size{20U} ;
386} ;
387
388#endif
A base interface for GSsl::Digester pimple classes.
Definition: gssl.h:472
virtual std::string state()=0
Implements Digester::state().
virtual std::size_t blocksize() const noexcept=0
Implements Digester::blocksize().
virtual std::string value()=0
Implements Digester::value().
virtual void add(G::string_view)=0
Implements Digester::add().
A class for objects that can perform a cryptographic hash.
Definition: gssl.h:215
A base interface for GSsl::Library pimple classes.
Definition: gssl.h:385
virtual bool hasProfile(const std::string &profile_name) const =0
Implements Library::hasProfile().
virtual const Profile & profile(const std::string &profile_name) const =0
Implements Library::profile().
virtual Digester digester(const std::string &, const std::string &, bool) const =0
Implements Library::digester().
virtual std::string id() const =0
Implements Library::id().
virtual G::StringArray digesters(bool) const =0
Implements Library::digesters().
virtual void addProfile(const std::string &, bool, const std::string &, const std::string &, const std::string &, const std::string &, const std::string &, const std::string &)=0
Implements Library::addProfile().
Holds a mbedtls_x509_crt structure.
Definition: gssl_mbedtls.h:54
Holds protocol version information, etc.
Definition: gssl_mbedtls.h:187
Holds a mbedtls_ssl_context structure.
Definition: gssl_mbedtls.h:122
An exception class for GSsl::MbedTls classes.
Definition: gssl_mbedtls.h:143
Holds a mbedtls_pk_context structure.
Definition: gssl_mbedtls.h:100
Holds a mbedtls_ctr_drbg_context structure.
Definition: gssl_mbedtls.h:78
An interface for reading a sensitive file and then overwriting its contents in memory.
Definition: gssl_mbedtls.h:157
A base interface for profile classes that work with concrete classes derived from GSsl::LibraryImpBas...
Definition: gssl.h:419
virtual std::unique_ptr< ProtocolImpBase > newProtocol(const std::string &, const std::string &) const =0
Factory method for a new Protocol object.
An abstract interface for reading and writing from a non-blocking i/o channel.
Definition: greadwrite.h:50
A class like c++17's std::string_view.
Definition: gstringview.h:51
An interface to an underlying TLS library.
TLS/SSL transport layer security classes.
Definition: gssl.h:36
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstringarray.h:30
STL namespace.