47DtlsSocket::DtlsSocket(std::unique_ptr<DtlsSocketContext> socketContext,
DtlsFactory* factory,
enum SocketType type):
48 mSocketContext(std::move(socketContext)),
50 mSsl(newSsl(factory, type)),
51 mInBio(SSL_get_rbio(mSsl)),
52 mOutBio(SSL_get_wbio(mSsl)),
54 mHandshakeCompleted(false),
55 mHandshakeFailed(false),
56 mCreated(std::chrono::steady_clock::now())
58 mSocketContext->setDtlsSocket(
this);
61DtlsSocket::DtlsSocket(std::unique_ptr<DtlsSocketContext> socketContext,
DtlsFactory* factory,
SSL* acceptedSsl,
const std::string& peer):
62 mSocketContext(std::move(socketContext)),
65 mInBio(SSL_get_rbio(acceptedSsl)),
66 mOutBio(SSL_get_wbio(acceptedSsl)),
68 mHandshakeCompleted(false),
69 mHandshakeFailed(false),
70 mCreated(std::chrono::steady_clock::now()),
73 mSocketContext->setDtlsSocket(
this);
77 SSL_set_ex_data(mSsl, DtlsFactory::cookiePeerIndex(), &mCookiePeer);
81DtlsSocket::newSsl(
DtlsFactory* factory, SocketType type)
84 SSL* ssl=SSL_new(factory->mContext);
90 SSL_set_connect_state(ssl);
93 SSL_set_accept_state(ssl);
94 SSL_set_verify(ssl,SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
dummy_cb);
102 SSL_set_bio(ssl, BIO_new(BIO_s_mem()), BIO_new(BIO_s_mem()));
106 SSL_set_options(ssl, SSL_OP_NO_QUERY_MTU);
107 DTLS_set_link_mtu(ssl, (
long)factory->mMtu);
113 if(mReadTimer) mReadTimer->invalidate();
126 if(timer == mReadTimer.get())
139 doHandshakeIteration();
154 r=BIO_write(mInBio,bytes,(
int)len);
158 if(mHandshakeCompleted)
160 handlePacketAfterHandshake();
164 doHandshakeIteration();
171DtlsSocket::handleTimeout()
173 if(mHandshakeCompleted || mHandshakeFailed)
176 if(serverHandshakeTimeLeft() <= std::chrono::steady_clock::duration::zero())
178 mHandshakeFailed =
true;
179 mSocketContext->handshakeFailed(
"DTLS handshake not completed in time");
190 if(DTLSv1_handle_timeout(mSsl) < 0)
194 ERR_error_string_n(ERR_peek_error(),errbuf,
sizeof(errbuf));
195 mHandshakeFailed =
true;
196 mSocketContext->handshakeFailed(errbuf[0] ? errbuf :
"DTLS handshake timed out");
205DtlsSocket::handlePacketAfterHandshake()
211 unsigned char buffer[2048];
212 while(SSL_read(mSsl, buffer,
sizeof(buffer)) > 0)
221DtlsSocket::writeOutput()
227 unsigned char *outBioData;
228 int outBioLen=BIO_get_mem_data(mOutBio,&outBioData);
229 const size_t len = outBioLen > 0 ? (size_t)outBioLen : 0;
230 const size_t mtu = mFactory->mMtu;
231 size_t datagramStart = 0;
233 while(pos + 13 <= len)
235 const size_t recordLen = 13 + ((size_t)outBioData[pos + 11] << 8 | outBioData[pos + 12]);
236 if(pos + recordLen > len)
240 if(pos > datagramStart && pos + recordLen - datagramStart > mtu)
242 mSocketContext->write(outBioData + datagramStart, (
unsigned int)(pos - datagramStart));
247 if(len > datagramStart)
249 mSocketContext->write(outBioData + datagramStart, (
unsigned int)(len - datagramStart));
253std::chrono::steady_clock::duration
254DtlsSocket::serverHandshakeTimeLeft()
const
256 if(mSocketType !=
Server || mFactory->mServerHandshakeTimeout == 0)
258 return (std::chrono::steady_clock::duration::max)();
260 return std::chrono::seconds(mFactory->mServerHandshakeTimeout) -
getAge();
264DtlsSocket::scheduleTimer()
269 mReadTimer->invalidate();
276 if(!mHandshakeCompleted && !mHandshakeFailed && DTLSv1_get_timeout(mSsl, &tv) == 1)
278 unsigned int waitMs = (
unsigned int)tv.tv_sec * 1000 + ((
unsigned int)tv.tv_usec + 999) / 1000;
280 const std::chrono::steady_clock::duration timeLeft = serverHandshakeTimeLeft();
281 if(timeLeft != (std::chrono::steady_clock::duration::max)())
283 const long long timeLeftMs = std::chrono::duration_cast<std::chrono::milliseconds>(timeLeft).count() + 1;
284 if(timeLeftMs < (
long long)waitMs)
286 waitMs = timeLeftMs > 0 ? (
unsigned int)timeLeftMs : 1;
289 mReadTimer = std::make_shared<DtlsSocketTimer>(0,
this);
290 mReadTimer->setLock(mSocketContext->timerLock());
291 mFactory->mTimerContext->addTimer(mReadTimer, waitMs > 0 ? waitMs : 1);
296DtlsSocket::doHandshakeIteration()
302 if(mHandshakeCompleted || mHandshakeFailed)
309 r=SSL_do_handshake(mSsl);
311 ERR_error_string_n(ERR_peek_error(),errbuf,
sizeof(errbuf));
314 switch(sslerr=SSL_get_error(mSsl,r))
317 mHandshakeCompleted =
true;
318 mSocketContext->handshakeCompleted();
320 case SSL_ERROR_WANT_READ:
324 cerr <<
"SSL error " << sslerr << endl;
326 mHandshakeFailed =
true;
327 mSocketContext->handshakeFailed(errbuf);
342 for(; *a && *b; a++, b++)
344 if(tolower((
unsigned char)*a) != tolower((
unsigned char)*b))
355 if(!hashFunction)
return 0;
378#if OPENSSL_VERSION_NUMBER < 0x30000000L
379 x=SSL_get_peer_certificate(mSsl);
381 x=SSL_get1_peer_certificate(mSsl);
394 char fprint[EVP_MAX_MD_SIZE * 3];
397 return fingerprint &&
416 switch(negotiated->id)
418 case SRTP_AES128_CM_SHA1_80: profile = srtp_profile_aes128_cm_sha1_80;
break;
419 case SRTP_AES128_CM_SHA1_32: profile = srtp_profile_aes128_cm_sha1_32;
break;
420 case SRTP_AEAD_AES_128_GCM: profile = srtp_profile_aead_aes_128_gcm;
break;
421 case SRTP_AEAD_AES_256_GCM: profile = srtp_profile_aead_aes_256_gcm;
break;
422 default:
return false;
425 srtp_crypto_policy_t policy;
426 return srtp_crypto_policy_set_from_profile_for_rtp(&policy, profile) == srtp_err_status_ok &&
427 srtp_crypto_policy_set_from_profile_for_rtcp(&policy, profile) == srtp_err_status_ok;
438 srtp_profile_t profile;
443 unsigned int keyLen = srtp_profile_get_master_key_length(profile);
444 unsigned int saltLen = srtp_profile_get_master_salt_length(profile);
447 unsigned char material[2 * SRTP_MAX_KEY_LEN];
448 size_t materialLen = 2 * (keyLen + saltLen);
449 if(materialLen >
sizeof(material) ||
450 !SSL_export_keying_material(
454 "EXTRACTOR-dtls_srtp", 19, NULL, 0, 0))
461 keys.
clientMasterKey.assign(material + offset, material + offset + keyLen);
463 keys.
serverMasterKey.assign(material + offset, material + offset + keyLen);
465 keys.
clientMasterSalt.assign(material + offset, material + offset + saltLen);
467 keys.
serverMasterSalt.assign(material + offset, material + offset + saltLen);
470 OPENSSL_cleanse(material,
sizeof(material));
474SRTP_PROTECTION_PROFILE*
479 return SSL_get_selected_srtp_profile(mSsl);
492 unsigned char md[EVP_MAX_MD_SIZE];
495 if(X509_digest(cert,
digest,md,&n) != 1 || n == 0 ||
496 fingerprintSize < n * 3)
501 static const char hex[] =
"0123456789ABCDEF";
502 for(
unsigned int i=0;i<n;i++)
504 *fingerprint++ = hex[md[i] >> 4];
505 *fingerprint++ = hex[md[i] & 0x0f];
506 *fingerprint++ = (i < n-1) ?
':' : 0;
513initSrtpPolicy(srtp_policy_t& policy, srtp_profile_t profile,
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& salt)
515 memset(&policy, 0,
sizeof(srtp_policy_t));
516 policy.window_size = 128;
517 policy.allow_repeat_tx = 1;
520 memcpy(keyAndSalt, key.data(), key.size());
521 memcpy(keyAndSalt + key.size(), salt.data(), salt.size());
522 policy.key = keyAndSalt;
525 srtp_crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile);
526 srtp_crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
535 srtp_profile_t profile;
547 srtp_policy_t client_policy;
549 srtp_policy_t server_policy;
552 if (mSocketType ==
Client)
554 client_policy.ssrc.type = ssrc_any_outbound;
555 outboundPolicy = client_policy;
557 server_policy.ssrc.type = ssrc_any_inbound;
558 inboundPolicy = server_policy;
562 server_policy.ssrc.type = ssrc_any_outbound;
563 outboundPolicy = server_policy;
565 client_policy.ssrc.type = ssrc_any_inbound;
566 inboundPolicy = client_policy;
584 if(mSsl) SSL_free(mSsl);
589 std::vector<unsigned char>& response,
590 const std::function<std::unique_ptr<DtlsSocketContext>()>& makeContext)
601 SSL_set_ex_data(mSsl, DtlsFactory::cookiePeerIndex(), &mPeer);
605 BIO* inBio = SSL_get_rbio(mSsl);
606 BIO* outBio = SSL_get_wbio(mSsl);
609 int r = BIO_write(inBio, bytes, (
int)len);
615 BIO_ADDR* address = BIO_ADDR_new();
616 r = DTLSv1_listen(mSsl, address);
617 BIO_ADDR_free(address);
619 unsigned char* out = 0;
620 long outLen = BIO_get_mem_data(outBio, &out);
623 response.assign(out, out + outLen);
643 socket->doHandshakeIteration();
static const EVP_MD * fingerprintDigest(const char *hashFunction)
static bool equalsIgnoreCase(const char *a, const char *b)
static void initSrtpPolicy(srtp_policy_t &policy, srtp_profile_t profile, const std::vector< unsigned char > &key, const std::vector< unsigned char > &salt)
int dummy_cb(int d, X509_STORE_CTX *x)
static bool negotiatedSrtpProfile(SRTP_PROTECTION_PROFILE *negotiated, srtp_profile_t &profile)
static Data digest("digest")
#define resip_assert(x)
This file needs to work for both C and C++ code.
void getMyCertFingerprint(char *fingerprint)
static PacketType demuxPacket(const unsigned char *buf, size_t len)
DtlsSocket * handlePacket(const unsigned char *bytes, size_t len, const std::string &peer, std::vector< unsigned char > &response, const std::function< std::unique_ptr< DtlsSocketContext >()> &makeContext)
DtlsSocketTimer(unsigned int seq, DtlsSocket *socket)
std::chrono::steady_clock::duration getAge() const
static const size_t FingerprintSize
bool createSrtpSessionPolicies(srtp_policy_t &outboundPolicy, srtp_policy_t &inboundPolicy)
static void computeFingerprint(X509 *cert, char *fingerprint)
static bool isFingerprintHashFunctionSupported(const char *hashFunction)
bool checkFingerprint(const char *hashFunction, const char *fingerprint)
SRTP_PROTECTION_PROFILE * getSrtpProfile()
bool getRemoteFingerprint(const char *hashFunction, char *fingerprint, size_t fingerprintSize)
void expired(DtlsSocketTimer *)
void getMyCertFingerprint(char *fingerprint)
bool handlePacketMaybe(const unsigned char *bytes, size_t len)
SrtpSessionKeys getSrtpSessionKeys()
std::vector< unsigned char > serverMasterSalt
std::vector< unsigned char > clientMasterKey
std::vector< unsigned char > clientMasterSalt
std::vector< unsigned char > serverMasterKey