E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gssl.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 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 // gssl.cpp
19 //
20
21 #include "gdef.h"
22 #include "gssl.h"
23 #include "gstr.h"
24 #include "gexception.h"
25 #include "glog.h"
26 #include <algorithm>
27
28 GSsl::Library * GSsl::Library::m_this = nullptr ;
29
30 GSsl::Library::Library( bool active , const std::string & library_config , LogFn log_fn , bool verbose ) :
31 m_imp(nullptr)
32 {
33 if( m_this == nullptr )
34 m_this = this ;
35
36 if( active )
37 {
38 G::StringArray config = G::Str::splitIntoTokens( library_config , "," ) ;
39
40 // TODO remove backwards compatibility for numeric tls-config flags
41 if( G::Str::isUInt(library_config) )
42 {
43 G_WARNING( "GSsl::Library::ctor: tls-config: numeric tls configuration flags are deprecated" ) ;
44 unsigned int flags = G::Str::toUInt( library_config ) ;
45 if( (flags&(~3U)) == 0U )
46 config.clear() ;
47 if( (flags&3U) == 2U )
48 config.push_back( "sslv23" ) ;
49 else if( (flags&3U) == 3U )
50 config.push_back( "sslv3" ) ;
51 }
52
53 m_imp = newLibraryImp( config , log_fn , verbose ) ;
54
55 if( !config.empty() )
56 G_WARNING( "GSsl::Library::Library: tls-config: tls configuration items ignored: [" << G::Str::join(",",config) << "]" ) ;
57 }
58 }
59
60 GSsl::Library::~Library()
61 {
62 delete m_imp ;
63 if( m_this == nullptr )
64 m_this = nullptr ;
65 }
66
67 bool GSsl::Library::real()
68 {
69 return true ;
70 }
71
72 GSsl::Library * GSsl::Library::instance()
73 {
74 return m_this ;
75 }
76
77 bool GSsl::Library::enabled() const
78 {
79 return m_imp != nullptr ;
80 }
81
82 std::string GSsl::Library::id() const
83 {
84 return m_imp->id() ;
85 }
86
87 void GSsl::Library::addProfile( const std::string & profile_name , bool is_server_profile ,
88 const std::string & key_file , const std::string & cert_file , const std::string & ca_file ,
89 const std::string & default_peer_certificate_name , const std::string & default_peer_host_name ,
90 const std::string & profile_config )
91 {
92 if( m_imp != nullptr )
93 m_imp->addProfile( profile_name , is_server_profile , key_file , cert_file , ca_file ,
94 default_peer_certificate_name , default_peer_host_name , profile_config ) ;
95 }
96
97 bool GSsl::Library::hasProfile( const std::string & profile_name ) const
98 {
99 return m_imp->hasProfile( profile_name ) ;
100 }
101
102 const GSsl::Profile & GSsl::Library::profile( const std::string & profile_name ) const
103 {
104 if( !imp().hasProfile(profile_name) )
105 throw G::Exception( "invalid tls profile name [" + profile_name + "]" ) ;
106 return imp().profile( profile_name ) ;
107 }
108
109 bool GSsl::Library::enabledAs( const std::string & profile_name )
110 {
111 return instance() != nullptr && instance()->enabled() && instance()->hasProfile( profile_name ) ;
112 }
113
114 GSsl::LibraryImpBase & GSsl::Library::impstance()
115 {
116 if( instance() == nullptr )
117 throw G::Exception( "no tls library instance" ) ;
118 return instance()->imp() ;
119 }
120
121 GSsl::LibraryImpBase & GSsl::Library::imp()
122 {
123 if( m_imp == nullptr )
124 throw G::Exception( "no tls library instance" ) ;
125 return *m_imp ;
126 }
127
128 const GSsl::LibraryImpBase & GSsl::Library::imp() const
129 {
130 if( m_imp == nullptr )
131 throw G::Exception( "no tls library instance" ) ;
132 return *m_imp ;
133 }
134
135 void GSsl::Library::log( int level , const std::string & log_line )
136 {
137 if( level == 1 )
138 G_DEBUG( "GSsl::Library::log: tls: " << log_line ) ;
139 else if( level == 2 )
140 G_LOG( "GSsl::Library::log: tls: " << log_line ) ;
141 else
142 G_WARNING( "GSsl::Library::log: tls: " << log_line ) ;
143 }
144
145 G::StringArray GSsl::Library::digesters( bool require_state )
146 {
147 return instance() == nullptr || instance()->m_imp == nullptr ? G::StringArray() : impstance().digesters(require_state) ;
148 }
149
150 GSsl::Digester GSsl::Library::digester( const std::string & hash_function , const std::string & state ) const
151 {
152 return impstance().digester( hash_function , state ) ;
153 }
154
155 // ==
156
157 GSsl::Protocol::Protocol( const Profile & profile , const std::string & peer_certificate_name , const std::string & peer_host_name ) :
158 m_imp( profile.newProtocol(peer_certificate_name,peer_host_name) )
159 {
160 }
161
162 GSsl::Protocol::~Protocol()
163 {
164 delete m_imp ;
165 }
166
167 std::string GSsl::Protocol::peerCertificate() const
168 {
169 return m_imp->peerCertificate() ;
170 }
171
172 std::string GSsl::Protocol::peerCertificateChain() const
173 {
174 return m_imp->peerCertificateChain() ;
175 }
176
177 bool GSsl::Protocol::verified() const
178 {
179 return m_imp->verified() ;
180 }
181
182 std::string GSsl::Protocol::str( Result result )
183 {
184 if( result == Result_ok ) return "Result_ok" ;
185 if( result == Result_read ) return "Result_read" ;
186 if( result == Result_write ) return "Result_write" ;
187 if( result == Result_error ) return "Result_error" ;
188 return "Result_undefined" ;
189 }
190
191 GSsl::Protocol::Result GSsl::Protocol::connect( G::ReadWrite & io )
192 {
193 return m_imp->connect( io ) ;
194 }
195
196 GSsl::Protocol::Result GSsl::Protocol::accept( G::ReadWrite & io )
197 {
198 return m_imp->accept( io ) ;
199 }
200
201 GSsl::Protocol::Result GSsl::Protocol::read( char * buffer , size_t buffer_size_in , ssize_t & data_size_out )
202 {
203 return m_imp->read( buffer , buffer_size_in , data_size_out ) ;
204 }
205
206 GSsl::Protocol::Result GSsl::Protocol::write( const char * buffer , size_t data_size_in , ssize_t & data_size_out)
207 {
208 return m_imp->write( buffer , data_size_in , data_size_out ) ;
209 }
210
211 GSsl::Protocol::Result GSsl::Protocol::stop()
212 {
213 return m_imp->stop() ;
214 }
215
216 // ==
217
218 GSsl::Digester::Digester( DigesterImpBase * p ) :
219 m_imp(p)
220 {
221 }
222
223 void GSsl::Digester::add( const std::string & s )
224 {
225 m_imp->add( s ) ;
226 }
227
228 std::string GSsl::Digester::value()
229 {
230 return m_imp->value() ;
231 }
232
233 std::string GSsl::Digester::state()
234 {
235 return m_imp->state() ;
236 }
237
238 size_t GSsl::Digester::blocksize() const
239 {
240 return m_imp->blocksize() ;
241 }
242
243 size_t GSsl::Digester::valuesize() const
244 {
245 return m_imp->valuesize() ;
246 }
247
248 size_t GSsl::Digester::statesize() const
249 {
250 return m_imp->statesize() ;
251 }
252
253 // ==
254
255 GSsl::LibraryImpBase::~LibraryImpBase()
256 {
257 }
258
259 bool GSsl::LibraryImpBase::consume( G::StringArray & list , const std::string & key )
260 {
261 G::StringArray::iterator p = std::find( list.begin() , list.end() , key ) ;
262 if( p != list.end() )
263 {
264 list.erase( p ) ;
265 return true ;
266 }
267 else
268 {
269 return false ;
270 }
271 }
272
273 // ==
274
275 GSsl::Profile::~Profile()
276 {
277 }
278
279 GSsl::ProtocolImpBase::~ProtocolImpBase()
280 {
281 }
282
283 GSsl::DigesterImpBase::~DigesterImpBase()
284 {
285 }
286
287 /// \file gssl.cpp
GSsl::Profile
A base interface for profile classes that work with concrete classes derived from GSsl::LibraryImpBas...
Definition: gssl.h:392
GSsl::Library::instance
static Library * instance()
Returns a pointer to a library object, if any.
Definition: gssl.cpp:72
GSsl::Protocol::peerCertificateChain
std::string peerCertificateChain() const
Returns the peer certificate chain in PEM format, starting with the peer certificate and progressing ...
Definition: gssl.cpp:172
gssl.h
An interface to an underlying TLS library.
GSsl::Library::digester
Digester digester(const std::string &name, const std::string &state=std::string()) const
Returns a digester object.
Definition: gssl.cpp:150
G::ReadWrite
An abstract interface for reading and writing from a non-blocking i/o channel.
Definition: greadwrite.h:49
GSsl::LibraryImpBase::~LibraryImpBase
virtual ~LibraryImpBase()
Destructor.
Definition: gssl.cpp:255
GSsl::Digester::state
std::string state()
Returns the intermediate state.
Definition: gssl.cpp:233
glog.h
GSsl::Library::digesters
static G::StringArray digesters(bool require_state=false)
Returns a list of hash function names (such as "MD5") that the TLS library can do, ordered roughly from strongest to weakest.
Definition: gssl.cpp:145
GSsl::Library::hasProfile
bool hasProfile(const std::string &profile_name) const
Returns true if the named profile has been add()ed.
Definition: gssl.cpp:97
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
GSsl::Library::enabledAs
static bool enabledAs(const std::string &profile_name)
A static convenience function that returns true if there is an enabled() Library instance() that has ...
Definition: gssl.cpp:109
G::Str::splitIntoTokens
static void splitIntoTokens(const std::string &in, StringArray &out, const std::string &ws)
Splits the string into 'ws'-delimited tokens.
Definition: gstr.cpp:908
GSsl::Protocol::str
static std::string str(Result result)
Converts a result enumeration into a printable string.
Definition: gssl.cpp:182
GSsl::Library::addProfile
void addProfile(const std::string &profile_name, bool is_server_profile, const std::string &key_file=std::string(), const std::string &cert_file=std::string(), const std::string &ca_path=std::string(), const std::string &default_peer_certificate_name=std::string(), const std::string &default_peer_host_name=std::string(), const std::string &profile_config=std::string())
Creates a named Profile object that can be retrieved by profile().
Definition: gssl.cpp:87
GSsl::Profile::~Profile
virtual ~Profile()
Destructor.
Definition: gssl.cpp:275
GSsl::Library::~Library
~Library()
Destructor. Cleans up the underlying TLS library.
Definition: gssl.cpp:60
GSsl::Library::log
static void log(int level, const std::string &line)
The default logging callback function, where the level is 1 for debug, 2 for info, 3 for warnings, and 4 for errors.
Definition: gssl.cpp:135
GSsl::DigesterImpBase
A base interface for GSsl::Digester pimple classes.
Definition: gssl.h:439
GSsl::Library::impstance
static LibraryImpBase & impstance()
Returns a reference to the pimple object when enabled().
Definition: gssl.cpp:114
GSsl::Protocol::Protocol
Protocol(const Profile &, const std::string &peer_certificate_name=std::string(), const std::string &peer_host_name=std::string())
Constructor.
Definition: gssl.cpp:157
G::Str::toUInt
static unsigned int toUInt(const std::string &s)
Converts string 's' to an unsigned int.
Definition: gstr.cpp:488
gstr.h
GSsl::Protocol::stop
Result stop()
Initiates the protocol shutdown.
Definition: gssl.cpp:211
GSsl::Digester
Returns an object that can perform a cryptographic hash.
Definition: gssl.h:194
GSsl::Protocol::read
Result read(char *buffer, size_t buffer_size_in, ssize_t &data_size_out)
Reads user data into the supplied buffer.
Definition: gssl.cpp:201
GSsl::Protocol::accept
Result accept(G::ReadWrite &io)
Starts the protocol passively (as a server).
Definition: gssl.cpp:196
GSsl::LibraryImpBase::consume
static bool consume(G::StringArray &list, const std::string &item)
A convenience function that removes the item from the list and returns true iff is was removed...
Definition: gssl.cpp:259
GSsl::LibraryImpBase
A base interface for GSsl::Library pimple classes.
Definition: gssl.h:358
GSsl::Digester::value
std::string value()
Returns the hash value.
Definition: gssl.cpp:228
GSsl::Protocol::connect
Result connect(G::ReadWrite &io)
Starts the protocol actively (as a client).
Definition: gssl.cpp:191
GSsl::Digester::Digester
Digester(DigesterImpBase *)
Constructor, used by the Library class.
Definition: gssl.cpp:218
GSsl::Library::profile
const Profile & profile(const std::string &profile_name) const
Returns an opaque reference to the named profile.
Definition: gssl.cpp:102
GSsl::Protocol::peerCertificate
std::string peerCertificate() const
Returns the peer certificate in PEM format.
Definition: gssl.cpp:167
GSsl::Digester::valuesize
size_t valuesize() const
Returns the hash function's value size in bytes.
Definition: gssl.cpp:243
GSsl::Library::Library
Library(bool active=true, const std::string &library_config=std::string(), LogFn=Library::log, bool verbose=true)
Constructor.
Definition: gssl.cpp:30
GSsl::Digester::add
void add(const std::string &)
Adds data of arbitrary size.
Definition: gssl.cpp:223
GSsl::Protocol::write
Result write(const char *buffer, size_t data_size_in, ssize_t &data_size_out)
Writes user data.
Definition: gssl.cpp:206
gexception.h
imp
Definition: gbase64.cpp:27
G::Exception
A general-purpose exception class derived from std::exception and containing a std::string.
Definition: gexception.h:43
GSsl::Library
A singleton class for initialising the underlying TLS library.
Definition: gssl.h:234
G::Str::join
static std::string join(const std::string &sep, const StringArray &strings)
Concatenates an array of strings with separators.
Definition: gstr.cpp:1023
GSsl::Library::real
static bool real()
Returns true if this is a real TLS library.
Definition: gssl.cpp:67
GSsl::Protocol::~Protocol
~Protocol()
Destructor.
Definition: gssl.cpp:162
GSsl::Digester::statesize
size_t statesize() const
Returns the size of the state() string in bytes, or zero if state() is not implemented.
Definition: gssl.cpp:248
GSsl::DigesterImpBase::~DigesterImpBase
virtual ~DigesterImpBase()
Destructor.
Definition: gssl.cpp:283
GSsl::Library::enabled
bool enabled() const
Returns true if this is a real TLS library and the constructor's active parameter was set...
Definition: gssl.cpp:77
G::Str::isUInt
static bool isUInt(const std::string &s)
Returns true if the string can be converted into an unsigned integer without throwing an exception...
Definition: gstr.cpp:304
GSsl::Digester::blocksize
size_t blocksize() const
Returns the hash function's block size in bytes.
Definition: gssl.cpp:238
GSsl::Protocol::verified
bool verified() const
Returns true if the peer certificate has been verified.
Definition: gssl.cpp:177
GSsl::Library::id
std::string id() const
Returns the TLS library name and version.
Definition: gssl.cpp:82
GSsl::ProtocolImpBase::~ProtocolImpBase
virtual ~ProtocolImpBase()
Destructor.
Definition: gssl.cpp:279