reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
TlsBaseTransport.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
5#ifdef USE_SSL
6
7#include <memory>
8#include <stdexcept>
9
10#include "rutil/compat.hxx"
11#include "rutil/Data.hxx"
12#include "rutil/Socket.hxx"
13#include "rutil/Logger.hxx"
18
19#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
20
21using namespace std;
22using namespace resip;
23
25 int portNum,
26 IpVersion version,
27 const Data& interfaceObj,
28 Security& security,
29 const Data& sipDomain,
31 TransportType transportType,
33 Compression &compression,
34 unsigned transportFlags,
36 bool useEmailAsSIP,
37 const Data& certificateFilename,
38 const Data& privateKeyFilename,
39 const Data& privateKeyPassPhrase) :
40 TcpBaseTransport(fifo, portNum, version, interfaceObj, socketFunc, compression, transportFlags),
41 mSecurity(&security),
42 mSslType(sslType),
43 mDomainCtx(0),
44 mClientVerificationMode(cvm),
45 mUseEmailAsSIP(useEmailAsSIP),
46 mCertificateFilename(certificateFilename),
47 mPrivateKeyFilename(privateKeyFilename),
48 mPrivateKeyPassPhrase(privateKeyPassPhrase),
49 mReloadCertificate(false)
50{
51 setTlsDomain(sipDomain);
52 mTuple.setType(transportType);
53
54 init();
55
56 // If we have specified a sipDomain, then we need to create a new context for this domain,
57 // otherwise we will use the SSL Ctx or TLS Ctx created in the Security class
58 if(!sipDomain.empty())
59 {
60 switch(sslType)
61 {
63 DebugLog(<<"Using SecurityTypes::DynamicTLS");
64 break;
66 DebugLog(<<"Using SecurityTypes::TLSv1");
67 break;
68 default:
69 throw invalid_argument("Unrecognised SecurityTypes::SSLType value");
70 }
71 mDomainCtx = createDomainCtx();
72 }
73}
74
76TlsBaseTransport::createDomainCtx()
77{
78 // Built from the members rather than the constructor's arguments: the
79 // SSL_CTX keeps a pointer to the passphrase, and a reload needs them anyway
81 if(ctx)
82 {
84 {
85 // Lock TLS to version 1.0 - won't support 1.1, 1.2, 1.3, etc.
86 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
87 SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
88 }
89 if(mCertVerifyCallback)
90 {
91 SSL_CTX_set_cert_verify_callback(ctx, mCertVerifyCallback, mCertVerifyCallbackArg);
92 }
93 }
94 return ctx;
95}
96
97void
98TlsBaseTransport::reloadDomainCtx()
99{
100 if(!mDomainCtx)
101 {
102 // No domain, so this transport uses Security's shared SSL_CTX and has
103 // no certificate of its own to reload
104 return;
105 }
106
107 DebugLog(<<"TlsBaseTransport::reloadDomainCtx, re-reading certificate and private key for domain " << tlsDomain());
108 SSL_CTX* ctx = nullptr;
109 try
110 {
111 ctx = createDomainCtx();
112 }
113 catch(BaseException& e)
114 {
115 ErrLog(<<"Failed to reload the certificate/private key for domain " << tlsDomain() << ", still using the previous ones: " << e);
116 return;
117 }
118 catch(...)
119 {
120 ErrLog(<<"Failed to reload the certificate/private key for domain " << tlsDomain() << ", still using the previous ones");
121 return;
122 }
123 if(!ctx)
124 {
125 ErrLog(<<"Failed to reload the certificate/private key for domain " << tlsDomain() << ", still using the previous ones");
126 return;
127 }
128
129 // Connections set up with the old SSL_CTX hold their own reference to it,
130 // so it is only destroyed once the last of them has closed
131 SSL_CTX_free(mDomainCtx);
132 mDomainCtx = ctx;
133 InfoLog(<<"Reloaded the certificate and private key for domain " << tlsDomain());
134}
135
136
138{
139 if (mDomainCtx)
140 {
141 SSL_CTX_free(mDomainCtx);mDomainCtx=0;
142 }
143}
144
145void
147{
148 DebugLog(<<"TlsBaseTransport::onReload, setting mReloadCertificate for domain " << tlsDomain());
149 mReloadCertificate = true;
150}
151
152SSL_CTX*
154{
155 // FIXME: would be better to do this in a method called asynchronously after onReload
156 // as doing it here may slow down the connection.
157 // HUP is only likely to happen once per day for log reloads so the impact of doing it
158 // here is negligible
159 // exchange() so that a reload requested while this one runs isn't lost
160 if(mReloadCertificate.exchange(false))
161 {
162 reloadDomainCtx();
163 }
164
165 SSL_CTX *ctx = NULL;
166 if(mDomainCtx)
167 {
168 DebugLog(<<"Using TlsDomain-transport SSL_CTX");
169 ctx = mDomainCtx;
170 }
172 {
173 DebugLog(<<"Using SecurityTypes::DynamicTLS (dynamic version negotiation)");
174 ctx = mSecurity->getSslCtx();
175 }
176 else
177 {
178 DebugLog(<<"Using SecurityTypes::TLSv1 (pinned to TLSv1; 1.0 only)");
179 ctx = mSecurity->getTlsCtx();
180 }
181 return ctx;
182}
183
184bool
186 SecurityTypes::SSLVendor vendor, void *func, void *arg)
187{
188 // Only OpenSSL is supported at present
189 if(vendor != SecurityTypes::OpenSSL)
190 {
191 ErrLog(<<"refusing to set SSL callback for unknown SSL stack vendor");
192 return false;
193 }
194
195 // For full details of this callback see:
196 // https://www.openssl.org/docs/ssl/SSL_CTX_set_cert_verify_callback.html
197 mCertVerifyCallback = (int (*)(X509_STORE_CTX *,void *))func;
198 mCertVerifyCallbackArg = arg;
199 SSL_CTX_set_cert_verify_callback(getCtx(), mCertVerifyCallback, mCertVerifyCallbackArg);
200
201 return true;
202}
203
206{
208 Connection* conn = new TlsConnection(this,who, fd, mSecurity, server,
210 return conn;
211}
212
213#endif /* USE_SSL */
214
215/* ====================================================================
216 * The Vovida Software License, Version 1.0
217 *
218 * Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
219 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
220 *
221 * Redistribution and use in source and binary forms, with or without
222 * modification, are permitted provided that the following conditions
223 * are met:
224 *
225 * 1. Redistributions of source code must retain the above copyright
226 * notice, this list of conditions and the following disclaimer.
227 *
228 * 2. Redistributions in binary form must reproduce the above copyright
229 * notice, this list of conditions and the following disclaimer in
230 * the documentation and/or other materials provided with the
231 * distribution.
232 *
233 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
234 * and "Vovida Open Communication Application Library (VOCAL)" must
235 * not be used to endorse or promote products derived from this
236 * software without prior written permission. For written
237 * permission, please contact vocal@vovida.org.
238 *
239 * 4. Products derived from this software may not be called "VOCAL", nor
240 * may "VOCAL" appear in their name, without prior written
241 * permission of Vovida Networks, Inc.
242 *
243 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
244 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
245 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
246 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
247 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
248 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
249 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
251 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
252 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
254 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
255 * DAMAGE.
256 *
257 * ====================================================================
258 *
259 * This software consists of voluntary contributions made by Vovida
260 * Networks, Inc. and many individuals on behalf of Vovida Networks,
261 * Inc. For more information on Vovida Networks, Inc., please see
262 * <http://www.vovida.org/>.
263 *
264 */
struct ssl_ctx_st SSL_CTX
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert_not_null(x)
Handles cross-platform sockets compatibility.
The abstract base-class for all exceptions thrown by resip code.
SSL_CTX * getSslCtx()
SSL_CTX * getTlsCtx()
Connection implements, via sockets, ConnectionBase for managed connections.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
A templated, threadsafe message-queue class.
Definition Fifo.hxx:16
virtual SSL_CTX * createDomainCtx(const SSL_METHOD *method, const Data &domain, const Data &certificateFilename, const Data &privateKeyFilename, const Data &privateKeyPassPhrase)
Throws BaseSecurity::Exception if the certificate or private key can't be loaded; nothing is left all...
Definition Security.cxx:407
virtual void init()
Performs constructor activities that depend on virtual functions specified by derived classes.
std::atomic< bool > mReloadCertificate
bool setPeerCertificateVerificationCallback(SecurityTypes::SSLVendor vendor, void *func, void *arg)
Set a custom callback function to be used by the SSL stack to inspect the peer certificate.
SecurityTypes::SSLType mSslType
TlsBaseTransport(Fifo< TransactionMessage > &fifo, int portNum, IpVersion version, const Data &interfaceObj, Security &security, const Data &sipDomain, SecurityTypes::SSLType sslType, TransportType transportType, AfterSocketCreationFuncPtr socketFunc=0, Compression &compression=Compression::Disabled, unsigned transportFlags=0, SecurityTypes::TlsClientVerificationMode cvm=SecurityTypes::None, bool useEmailAsSIP=false, const Data &certificateFilename="", const Data &privateKeyFilename="", const Data &privateKeyPassPhrase="")
Connection * createConnection(const Tuple &who, Socket fd, bool server=false)
Makes new Connection using provided socket.
void setTlsDomain(const Data &domain)
Compression & mCompression
const Data & tlsDomain() const
Represents a network address.
Definition Tuple.hxx:59
void setType(TransportType type)
Definition Tuple.hxx:123
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
SSLType
Note: Before adding to the SSLType enum, please see the comments about mTlsCtx in resip/stack/ssl/Sec...
dcm! – add UnusedChecking(_enum) below;
void(* AfterSocketCreationFuncPtr)(Socket s, int transportType, const char *file, int line)
Definition Socket.hxx:107
int Socket
Definition Socket.hxx:94
TransportType
An enumeration of transport protocols.
IpVersion
An enumeration of IP versions.