reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
DtlsFactory.cxx
Go to the documentation of this file.
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#ifdef USE_SSL
6
7#include "rutil/ResipAssert.h"
8#include <iostream>
10
11#include <openssl/e_os2.h>
12#include <openssl/evp.h>
13#include <openssl/hmac.h>
14#include <openssl/rand.h>
15#include <openssl/err.h>
16#include <openssl/crypto.h>
17#include <openssl/ssl.h>
18
19#include "DtlsFactory.hxx"
20#include "DtlsSocket.hxx"
21
22#include <string>
23#include <utility>
24
25using namespace dtls;
26const char* DtlsFactory::DefaultSrtpProfile = "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32";
27
28DtlsFactory::DtlsFactory(std::unique_ptr<DtlsTimerContext> tc,X509 *cert, EVP_PKEY *privkey):
29 mTimerContext(std::move(tc)),
30 mCert(cert)
31{
32 int r;
33
34 mContext=SSL_CTX_new(DTLS_method());
35 resip_assert(mContext);
36
37 r=SSL_CTX_use_certificate(mContext, cert);
38 resip_assert(r==1);
39
41 resip_assert(r==1);
42
43 // Set SRTP profiles
45 resip_assert(r==0);
46
47 // DTLS cookies, for DtlsListener
48 r=RAND_bytes(mCookieSecret, sizeof(mCookieSecret));
49 resip_assert(r==1);
50 SSL_CTX_set_app_data(mContext, this);
51 SSL_CTX_set_cookie_generate_cb(mContext, generateCookie);
52 SSL_CTX_set_cookie_verify_cb(mContext, verifyCookie);
53}
54
59
60
62DtlsFactory::createClient(std::unique_ptr<DtlsSocketContext> context)
63{
64 return new DtlsSocket(std::move(context), this, DtlsSocket::Client);
65}
66
68DtlsFactory::createServer(std::unique_ptr<DtlsSocketContext> context)
69{
70 return new DtlsSocket(std::move(context), this, DtlsSocket::Server);
71}
72
73std::unique_ptr<DtlsListener>
75{
76 return std::unique_ptr<DtlsListener>(new DtlsListener(this));
77}
78
79int
80DtlsFactory::cookiePeerIndex()
81{
82 static const int index = SSL_get_ex_new_index(0, (void*)"dtls cookie peer", nullptr, nullptr, nullptr);
83 return index;
84}
85
86bool
87DtlsFactory::computeCookie(SSL* ssl, unsigned char* cookie, unsigned int* cookieLen)
88{
90 const std::string* peer = static_cast<const std::string*>(SSL_get_ex_data(ssl, cookiePeerIndex()));
91 if(!factory || !peer || peer->empty())
92 {
93 return false;
94 }
95 return HMAC(EVP_sha256(), factory->mCookieSecret, sizeof(factory->mCookieSecret),
96 (const unsigned char*)peer->data(), peer->size(), cookie, cookieLen) != nullptr;
97}
98
99int
100DtlsFactory::generateCookie(SSL* ssl, unsigned char* cookie, unsigned int* cookieLen)
101{
102 // cookie has room for DTLS1_COOKIE_LENGTH (255) bytes, the HMAC takes 32
103 return computeCookie(ssl, cookie, cookieLen) ? 1 : 0;
104}
105
106int
107DtlsFactory::verifyCookie(SSL* ssl, const unsigned char* cookie, unsigned int cookieLen)
108{
109 unsigned char expected[EVP_MAX_MD_SIZE];
110 unsigned int expectedLen = 0;
111 return computeCookie(ssl, expected, &expectedLen) &&
113}
114
115void
117{
118 DtlsSocket::computeFingerprint(mCert,fingerprint);
119}
120
121void
123{
124 int r;
125
127
128 resip_assert(r==0);
129}
130
131void
133{
134 int r;
135
136 r=SSL_CTX_set_cipher_list(mContext,str);
137 resip_assert(r==1);
138}
139
141DtlsFactory::demuxPacket(const unsigned char *data, size_t len)
142{
143 // By the first byte, as RFC 7983 section 7 sets out: 0-3 STUN, 20-63 DTLS, 128-191 RTP/RTCP.
144 // Anything else (eg. 16-19 ZRTP, 64-79 TURN ChannelData) is unknown, as is an empty datagram,
145 // which a peer can send.
146 if(len == 0)
147 return unknown;
148
149 if(data[0]<=3)
150 return stun;
151 if((data[0]>=128) && (data[0]<=191))
152 return rtp;
153 if((data[0]>=20) && (data[0]<=63))
154 return dtls;
155
156 return unknown;
157}
158
159#endif //USE_SSL
160
161
162/* ====================================================================
163
164 Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
165 Copyright (c) 2007-2008, Eric Rescorla and Derek MacDonald
166 All rights reserved.
167
168 Redistribution and use in source and binary forms, with or without
169 modification, are permitted provided that the following conditions are
170 met:
171
172 1. Redistributions of source code must retain the above copyright
173 notice, this list of conditions and the following disclaimer.
174
175 2. Redistributions in binary form must reproduce the above copyright
176 notice, this list of conditions and the following disclaimer in the
177 documentation and/or other materials provided with the distribution.
178
179 3. None of the contributors names may be used to endorse or promote
180 products derived from this software without specific prior written
181 permission.
182
183 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
184 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
187 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
188 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
189 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
190 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
191 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
192 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
193 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
194
195 ==================================================================== */
struct evp_pkey_st EVP_PKEY
struct x509_st X509
struct ssl_st SSL
static const Data cookie("z9hG4bK")
#define resip_assert(x)
This file needs to work for both C and C++ code.
DtlsSocket * createClient(std::unique_ptr< DtlsSocketContext > context)
DtlsSocket * createServer(std::unique_ptr< DtlsSocketContext > context)
static const char * DefaultSrtpProfile
void getMyCertFingerprint(char *fingerprint)
static PacketType demuxPacket(const unsigned char *buf, size_t len)
void setSrtpProfiles(const char *policyStr)
friend class DtlsSocket
friend class DtlsListener
void setCipherSuites(const char *cipherSuites)
DtlsFactory(std::unique_ptr< DtlsTimerContext > tc, X509 *cert, EVP_PKEY *privkey)
std::unique_ptr< DtlsListener > createListener()
static void computeFingerprint(X509 *cert, char *fingerprint)
void list()
Definition userAdmin.cxx:66