Skip to content

Commit

Permalink
[core] Fix crypto mode auto for listener sender (#2711).
Browse files Browse the repository at this point in the history
Co-authored-by: oviano <ovcollyer@mac.com>
  • Loading branch information
maxsharabayko and oviano committed Apr 17, 2023
1 parent b010763 commit 2fcd3d4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 14 deletions.
51 changes: 38 additions & 13 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4179,7 +4179,7 @@ EConnectStatus srt::CUDT::processRendezvous(

// The CryptoControl must be created by the prepareConnectionObjects() before interpreting and creating HSv5 extensions
// because the it will be used there.
if (!prepareConnectionObjects(m_ConnRes, m_SrtHsSide, NULL))
if (!prepareConnectionObjects(m_ConnRes, m_SrtHsSide, NULL) || !prepareBuffers(NULL))
{
// m_RejectReason already handled
HLOGC(cnlog.Debug,
Expand Down Expand Up @@ -4734,6 +4734,7 @@ EConnectStatus srt::CUDT::postConnect(const CPacket* pResponse, bool rendezvous,
// In this situation the interpretation of handshake was already done earlier.
ok = ok && pResponse->isControl();
ok = ok && interpretSrtHandshake(m_ConnRes, *pResponse, 0, 0);
ok = ok && prepareBuffers(eout);

if (!ok)
{
Expand Down Expand Up @@ -5548,7 +5549,7 @@ bool srt::CUDT::prepareConnectionObjects(const CHandShake &hs, HandshakeSide hsd
// code with HSv5 rendezvous, in which this will be run
// in a little bit "randomly selected" moment, but must
// be run once in the whole connection process.
if (m_pSndBuffer)
if (m_pCryptoControl)
{
HLOGC(rslog.Debug, log << CONID() << "prepareConnectionObjects: (lazy) already created.");
return true;
Expand All @@ -5573,9 +5574,29 @@ bool srt::CUDT::prepareConnectionObjects(const CHandShake &hs, HandshakeSide hsd
}
}

if (!createCrypter(hsd, bidirectional)) // Make sure CC is created (lazy)
{
if (eout)
*eout = CUDTException(MJ_SYSTEMRES, MN_MEMORY, 0);
m_RejectReason = SRT_REJ_RESOURCE;
return false;
}

return true;
}

bool srt::CUDT::prepareBuffers(CUDTException* eout)
{
if (m_pSndBuffer)
{
HLOGC(rslog.Debug, log << CONID() << "prepareBuffers: (lazy) already created.");
return true;
}

try
{
const int authtag = m_config.iCryptoMode == CSrtConfig::CIPHER_MODE_AES_GCM ? HAICRYPT_AUTHTAG_MAX : 0;
// CryptoControl has to be initialized and in case of RESPONDER the KM REQ must be processed (interpretSrtHandshake(..)) for the crypto mode to be deduced.
const int authtag = (m_pCryptoControl && m_pCryptoControl->getCryptoMode() == CSrtConfig::CIPHER_MODE_AES_GCM) ? HAICRYPT_AUTHTAG_MAX : 0;
m_pSndBuffer = new CSndBuffer(32, m_iMaxSRTPayloadSize, authtag);
SRT_ASSERT(m_iISN != -1);
m_pRcvBuffer = new srt::CRcvBuffer(m_iISN, m_config.iRcvBufSize, m_pRcvQueue->m_pUnitQueue, m_config.bMessageAPI);
Expand All @@ -5587,19 +5608,10 @@ bool srt::CUDT::prepareConnectionObjects(const CHandShake &hs, HandshakeSide hsd
{
// Simply reject.
if (eout)
{
*eout = CUDTException(MJ_SYSTEMRES, MN_MEMORY, 0);
}
m_RejectReason = SRT_REJ_RESOURCE;
return false;
}

if (!createCrypter(hsd, bidirectional)) // Make sure CC is created (lazy)
{
m_RejectReason = SRT_REJ_RESOURCE;
return false;
}

return true;
}

Expand Down Expand Up @@ -5710,6 +5722,19 @@ void srt::CUDT::acceptAndRespond(const sockaddr_any& agent, const sockaddr_any&
throw CUDTException(MJ_SETUP, MN_REJECTED, 0);
}

if (!prepareBuffers(NULL))
{
HLOGC(cnlog.Debug,
log << CONID() << "acceptAndRespond: prepareConnectionObjects failed - responding with REJECT.");
// If the SRT buffers failed to be allocated,
// the connection must be rejected.
//
// Respond with the rejection message and exit with exception
// so that the caller will know that this new socket should be deleted.
w_hs.m_iReqType = URQFailure(m_RejectReason);
throw CUDTException(MJ_SETUP, MN_REJECTED, 0);
}

// Synchronize the time NOW because the following function is about
// to use the start time to pass it to the receiver buffer data.
bool have_group = false;
Expand Down Expand Up @@ -9196,7 +9221,7 @@ int srt::CUDT::packLostData(CPacket& w_packet)

// The packet has been ecrypted, thus the authentication tag is expected to be stored
// in the SND buffer as well right after the payload.
if (m_config.iCryptoMode == CSrtConfig::CIPHER_MODE_AES_GCM)
if (m_pCryptoControl && m_pCryptoControl->getCryptoMode() == CSrtConfig::CIPHER_MODE_AES_GCM)
{
w_packet.setLength(w_packet.getLength() + HAICRYPT_AUTHTAG_MAX);
}
Expand Down
6 changes: 5 additions & 1 deletion srtcore/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,14 @@ class CUDT
EConnectStatus processRendezvous(const CPacket* response, const sockaddr_any& serv_addr, EReadStatus, CPacket& reqpkt);
void sendRendezvousRejection(const sockaddr_any& serv_addr, CPacket& request);

/// Create the CryptoControl object based on the HS packet. Allocates sender and receiver buffers and loss lists.
/// Create the CryptoControl object based on the HS packet.
SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock)
bool prepareConnectionObjects(const CHandShake &hs, HandshakeSide hsd, CUDTException *eout);

/// Allocates sender and receiver buffers and loss lists.
SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock)
bool prepareBuffers(CUDTException* eout);

SRT_ATR_NODISCARD SRT_ATTR_REQUIRES(m_ConnectionLock)
EConnectStatus postConnect(const CPacket* response, bool rendezvous, CUDTException* eout) ATR_NOEXCEPT;

Expand Down

1 comment on commit 2fcd3d4

@oviano
Copy link
Contributor

@oviano oviano commented on 2fcd3d4 Apr 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all seems to be working correctly for me using the Botan cryspr.

Please sign in to comment.