E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gssl_openssl.h
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 /// \file gssl_openssl.h
19 ///
20
21 #ifndef G_SSL_OPENSSL__H
22 #define G_SSL_OPENSSL__H
23
24 #include "gdef.h"
25 #include "gssl.h"
26 #include <openssl/ssl.h>
27 #include <openssl/err.h>
28 #include <openssl/rand.h>
29 #include <openssl/evp.h>
30 #include <map>
31
32 // debugging...
33 // * network logging
34 // $ sudo tcpdump -s 0 -n -i eth0 -X tcp port 587
35 // * emailrelay smtp proxy to gmail
36 // $ emailrelay --client-tls --forward-to smtp.gmail.com:587 ...
37 // * openssl smtp client to gmail
38 // $ openssl s_client -tls1 -msg -debug -starttls smtp -crlf -connect smtp.gmail.com:587
39 // * certificate
40 // $ openssl req -x509 -nodes -subj /CN=example.com -newkey rsa:1024 -keyout example.pem -out example.pem
41 // $ cp example.pem /etc/ssl/certs/
42 // $ cd /etc/ssl/certs && ln -s example.pem `openssl x509 -noout -hash -in example.pem`.0
43 // * openssl server (without smtp)
44 // $ openssl s_server -accept 10025 -cert /etc/ssl/certs/example.pem -debug -msg -tls1
45 //
46
47 namespace GSsl
48 {
49 namespace OpenSSL
50 {
51 class Error ;
52 class Certificate ;
53 class CertificateChain ;
54 class LibraryImp ;
55 class ProfileImp ;
56 class ProtocolImp ;
57 class DigesterImp ;
58 class Config ;
59 }
60 }
61
62 /// \class GSsl::OpenSSL::Certificate
63 /// Holds a certificate taken from an OpenSSL X509 structure.
64 ///
65 class GSsl::OpenSSL::Certificate
66 {
67 public:
68 Certificate( X509* , bool do_free ) ;
69 std::string str() const ;
70
71 private:
72 std::string m_str ;
73 } ;
74
75 /// \class GSsl::OpenSSL::Config
76 /// Holds protocol version information, etc.
77 ///
78 class GSsl::OpenSSL::Config
79 {
80 public:
81 typedef const SSL_METHOD * (*Fn)() ;
82 explicit Config( G::StringArray & config ) ;
83 Fn fn( bool server ) ;
84 long set() const ;
85 long reset() const ;
86 int min_() const ;
87 int max_() const ;
88 bool noverify() const ;
89
90 private:
91 static bool consume( G::StringArray & , const std::string & ) ;
92 static int map( int , int ) ;
93
94 private:
95 Fn m_server_fn ;
96 Fn m_client_fn ;
97 int m_min ;
98 int m_max ;
99 long m_options_set ;
100 long m_options_reset ;
101 bool m_noverify ;
102 } ;
103
104 /// \class GSsl::OpenSSL::CertificateChain
105 /// Holds a certificate chain taken from a stack of OpenSSL X509 structures.
106 ///
107 class GSsl::OpenSSL::CertificateChain
108 {
109 public:
110 explicit CertificateChain( STACK_OF(X509) * chain ) ;
111 std::string str() const ;
112
113 private:
114 std::string m_str ;
115 } ;
116
117 /// \class GSsl::OpenSSL::Error
118 /// An exception class for GSsl::OpenSSL classes.
119 ///
120 class GSsl::OpenSSL::Error : public std::exception
121 {
122 public:
123 explicit Error( const std::string & ) ;
124 Error( const std::string & , unsigned long ) ;
125 Error( const std::string & , unsigned long , const std::string & path ) ;
126 virtual ~Error() g__noexcept ;
127 virtual const char * what() const g__noexcept override ;
128 static void clearErrors() ;
129
130 private:
131 static std::string text( unsigned long ) ;
132
133 private:
134 std::string m_what ;
135 } ;
136
137 /// \class GSsl::OpenSSL::ProfileImp
138 /// An implementation of the GSsl::Profile interface for OpenSSL.
139 ///
140 class GSsl::OpenSSL::ProfileImp : public Profile
141 {
142 public:
143 typedef OpenSSL::Error Error ;
144
145 ProfileImp( const LibraryImp & , bool is_server_profile , const std::string & key_file ,
146 const std::string & cert_file , const std::string & ca_file ,
147 const std::string & default_peer_certificate_name , const std::string & default_peer_host_name ,
148 const std::string & profile_config ) ;
149 virtual ~ProfileImp() ;
150 SSL_CTX * p() const ;
151 const LibraryImp & lib() const ;
152 const std::string & defaultPeerCertificateName() const ;
153 const std::string & defaultPeerHostName() const ;
154 virtual ProtocolImpBase * newProtocol( const std::string & , const std::string & ) const override ;
155 void apply( const Config & ) ;
156
157 private:
158 ProfileImp( const ProfileImp & ) ;
159 void operator=( const ProfileImp & ) ;
160 static void check( int , const std::string & , const std::string & = std::string() ) ;
161 static int verifyPass( int , X509_STORE_CTX * ) ;
162 static int verifyPeerName( int , X509_STORE_CTX * ) ;
163 static std::string name( X509_NAME * ) ;
164 static void deleter( SSL_CTX * ) ;
165
166 private:
167 const LibraryImp & m_library_imp ;
168 const std::string m_default_peer_certificate_name ;
169 const std::string m_default_peer_host_name ;
170 unique_ptr<SSL_CTX,std::pointer_to_unary_function<SSL_CTX*,void> > m_ssl_ctx ;
171 } ;
172
173 /// \class GSsl::OpenSSL::LibraryImp
174 /// An implementation of the GSsl::LibraryImpBase interface for OpenSSL.
175 ///
176 class GSsl::OpenSSL::LibraryImp : public LibraryImpBase
177 {
178 public:
179 typedef GSsl::OpenSSL::Error Error ;
180
181 LibraryImp( G::StringArray & library_config , Library::LogFn , bool verbose ) ;
182 virtual ~LibraryImp() ;
183 virtual void addProfile( const std::string & name , bool is_server_profile ,
184 const std::string & key_file , const std::string & cert_file , const std::string & ca_file ,
185 const std::string & default_peer_certificate_name , const std::string & default_peer_host_name ,
186 const std::string & profile_config ) override ;
187 virtual bool hasProfile( const std::string & ) const override ;
188 virtual const GSsl::Profile & profile( const std::string & ) const override ;
189 virtual std::string id() const override ;
190 virtual G::StringArray digesters( bool ) const override ;
191 virtual Digester digester( const std::string & , const std::string & ) const override ;
192 Config config() const ;
193 bool noverify() const ;
194
195 Library::LogFn log() const ;
196 bool verbose() const ;
197 int index() const ;
198 static std::string credit( const std::string & prefix , const std::string & eol , const std::string & eot ) ;
199 static std::string sid() ;
200
201 private:
202 LibraryImp( const LibraryImp & ) ;
203 void operator=( const LibraryImp & ) ;
204 static void cleanup() ;
205
206 private:
207 typedef std::map<std::string,shared_ptr<ProfileImp> > Map ;
208 std::string m_library_config ;
209 mutable EVP_MD_CTX * m_evp_ctx ;
210 Library::LogFn m_log_fn ;
211 bool m_verbose ;
212 Map m_profile_map ;
213 int m_index ; // SSL_get_ex_new_index()
214 Config m_config ;
215 } ;
216
217 /// \class GSsl::OpenSSL::ProtocolImp
218 /// An implementation of the GSsl::ProtocolImpBase interface for OpenSSL.
219 ///
220 class GSsl::OpenSSL::ProtocolImp : public ProtocolImpBase
221 {
222 public:
223 typedef Protocol::Result Result ;
224 typedef OpenSSL::Error Error ;
225 typedef OpenSSL::Certificate Certificate ;
226 typedef OpenSSL::CertificateChain CertificateChain ;
227
228 ProtocolImp( const ProfileImp & , const std::string & , const std::string & ) ;
229 virtual ~ProtocolImp() ;
230 Result connect( G::ReadWrite & ) ;
231 Result accept( G::ReadWrite & ) ;
232 Result stop() ;
233 Result read( char * buffer , size_t buffer_size , ssize_t & read_size ) ;
234 Result write( const char * buffer , size_t size_in , ssize_t & size_out ) ;
235 std::string peerCertificate() const ;
236 std::string peerCertificateChain() const ;
237 bool verified() const ;
238 std::string requiredPeerCertificateName() const ;
239
240 private:
241 ProtocolImp( const ProtocolImp & ) ;
242 void operator=( const ProtocolImp & ) ;
243 int error( const char * , int ) const ;
244 void set( int ) ;
245 Result connect() ;
246 Result accept() ;
247 static Result convert( int ) ;
248 static void clearErrors() ;
249 void logErrors( const std::string & op , int rc , int e , const std::string & ) const ;
250 void saveResult() ;
251 static void deleter( SSL * ) ;
252
253 private:
254 const Profile & m_profile ;
255 unique_ptr<SSL,std::pointer_to_unary_function<SSL*,void> > m_ssl ;
256 Library::LogFn m_log_fn ;
257 bool m_verbose ;
258 bool m_fd_set ;
259 std::string m_required_peer_certificate_name ;
260 std::string m_peer_certificate ;
261 std::string m_peer_certificate_chain ;
262 bool m_verified ;
263 } ;
264
265 /// \class GSsl::OpenSSL::DigesterImp
266 /// An implementation of the GSsl::DigesterImpBase interface for OpenSSL.
267 ///
268 class GSsl::OpenSSL::DigesterImp : public GSsl::DigesterImpBase
269 {
270 public:
271 DigesterImp( const std::string & , const std::string & ) ;
272 virtual ~DigesterImp() ;
273 virtual void add( const std::string & ) override ;
274 virtual std::string value() override ;
275 virtual std::string state() override ;
276 virtual size_t blocksize() const override ;
277 virtual size_t valuesize() const override ;
278 virtual size_t statesize() const override ;
279
280 private:
281 DigesterImp( const DigesterImp & ) ;
282 void operator=( const DigesterImp & ) ;
283
284 private:
285 EVP_MD_CTX * m_evp_ctx ;
286 size_t m_block_size ;
287 size_t m_value_size ;
288 size_t m_state_size ;
289 } ;
290
291 #endif
GSsl::OpenSSL::ProtocolImp::peerCertificateChain
std::string peerCertificateChain() const
Implements Protocol::peerCertificateChain().
Definition: gssl_openssl.cpp:610
GSsl::Profile
A base interface for profile classes that work with concrete classes derived from GSsl::LibraryImpBas...
Definition: gssl.h:392
gssl.h
An interface to an underlying TLS library.
G::ReadWrite
An abstract interface for reading and writing from a non-blocking i/o channel.
Definition: greadwrite.h:49
GSsl::ProtocolImpBase
A base interface for GSsl::Protocol pimple classes.
Definition: gssl.h:405
GSsl::OpenSSL::ProtocolImp::write
Result write(const char *buffer, size_t size_in, ssize_t &size_out)
Implements Protocol::write().
Definition: gssl_openssl.cpp:584
GSsl::OpenSSL::ProtocolImp::accept
Result accept(G::ReadWrite &)
Implements Protocol::accept().
Definition: gssl_openssl.cpp:487
GSsl::OpenSSL::LibraryImp::digester
virtual Digester digester(const std::string &, const std::string &) const override
Implements Library::digester().
Definition: gssl_openssl.cpp:162
GSsl::OpenSSL::LibraryImp::digesters
virtual G::StringArray digesters(bool) const override
Implements Library::digesters().
Definition: gssl_openssl.cpp:145
GSsl::OpenSSL::ProfileImp::newProtocol
virtual ProtocolImpBase * newProtocol(const std::string &, const std::string &) const override
Factory method for a new Protocol object on the heap.
Definition: gssl_openssl.cpp:325
GSsl::OpenSSL::ProtocolImp::stop
Result stop()
Implements Protocol::stop().
Definition: gssl_openssl.cpp:556
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
GSsl::OpenSSL::LibraryImp
An implementation of the GSsl::LibraryImpBase interface for OpenSSL.
Definition: gssl_openssl.h:176
GSsl::DigesterImpBase
A base interface for GSsl::Digester pimple classes.
Definition: gssl.h:439
GSsl::OpenSSL::DigesterImp::add
virtual void add(const std::string &) override
Implements Digester::add().
Definition: gssl_openssl.cpp:209
GSsl::OpenSSL::Certificate
Holds a certificate taken from an OpenSSL X509 structure.
Definition: gssl_openssl.h:65
GSsl::OpenSSL::DigesterImp::statesize
virtual size_t statesize() const override
Implements Digester::statesize().
Definition: gssl_openssl.cpp:199
GSsl::OpenSSL::Config
Holds protocol version information, etc.
Definition: gssl_openssl.h:78
GSsl::OpenSSL::Error
An exception class for GSsl::OpenSSL classes.
Definition: gssl_openssl.h:120
GSsl::Digester
Returns an object that can perform a cryptographic hash.
Definition: gssl.h:194
GSsl::OpenSSL::CertificateChain
Holds a certificate chain taken from a stack of OpenSSL X509 structures.
Definition: gssl_openssl.h:107
GSsl::LibraryImpBase
A base interface for GSsl::Library pimple classes.
Definition: gssl.h:358
GSsl::OpenSSL::ProtocolImp::verified
bool verified() const
Implements Protocol::verified().
Definition: gssl_openssl.cpp:615
GSsl::OpenSSL::LibraryImp::addProfile
virtual void addProfile(const std::string &name, bool is_server_profile, const std::string &key_file, const std::string &cert_file, const std::string &ca_file, const std::string &default_peer_certificate_name, const std::string &default_peer_host_name, const std::string &profile_config) override
Implements Library::addProfile().
Definition: gssl_openssl.cpp:106
GSsl::OpenSSL::DigesterImp
An implementation of the GSsl::DigesterImpBase interface for OpenSSL.
Definition: gssl_openssl.h:268
GSsl::OpenSSL::ProtocolImp::read
Result read(char *buffer, size_t buffer_size, ssize_t &read_size)
Implements Protocol::read().
Definition: gssl_openssl.cpp:562
GSsl::OpenSSL::DigesterImp::valuesize
virtual size_t valuesize() const override
Implements Digester::valuesize().
Definition: gssl_openssl.cpp:194
GSsl::OpenSSL::ProtocolImp::connect
Result connect(G::ReadWrite &)
Implements Protocol::connect().
Definition: gssl_openssl.cpp:481
GSsl::OpenSSL::ProtocolImp::peerCertificate
std::string peerCertificate() const
Implements Protocol::peerCertificate().
Definition: gssl_openssl.cpp:605
GSsl::OpenSSL::DigesterImp::blocksize
virtual size_t blocksize() const override
Implements Digester::blocksize().
Definition: gssl_openssl.cpp:189
GSsl::OpenSSL::LibraryImp::hasProfile
virtual bool hasProfile(const std::string &) const override
Implements Library::hasProfile().
Definition: gssl_openssl.cpp:117
GSsl::OpenSSL::DigesterImp::state
virtual std::string state() override
Implements Digester::state().
Definition: gssl_openssl.cpp:204
GSsl
TLS/SSL transport layer security classes.
Definition: gssl.h:32
GSsl::OpenSSL::LibraryImp::id
virtual std::string id() const override
Implements Library::id().
Definition: gssl_openssl.cpp:86
GSsl::OpenSSL::LibraryImp::profile
virtual const GSsl::Profile & profile(const std::string &) const override
Implements Library::profile().
Definition: gssl_openssl.cpp:123
GSsl::OpenSSL::DigesterImp::value
virtual std::string value() override
Implements Digester::value().
Definition: gssl_openssl.cpp:214
GSsl::OpenSSL::ProtocolImp
An implementation of the GSsl::ProtocolImpBase interface for OpenSSL.
Definition: gssl_openssl.h:220
GSsl::OpenSSL::ProfileImp
An implementation of the GSsl::Profile interface for OpenSSL.
Definition: gssl_openssl.h:140