| 1578 | } |
| 1579 | |
| 1580 | bool CryptoBuiltInImpl::encode_rtps_message( |
| 1581 | DDS::OctetSeq& encoded_rtps_message, |
| 1582 | const DDS::OctetSeq& plain_rtps_message, |
| 1583 | ParticipantCryptoHandle sending_participant_crypto, |
| 1584 | const ParticipantCryptoHandleSeq& receiving_participant_crypto_list, |
| 1585 | CORBA::Long& receiving_participant_crypto_list_index, |
| 1586 | SecurityException& ex) |
| 1587 | { |
| 1588 | receiving_participant_crypto_list_index = static_cast<DDS::Int32>(receiving_participant_crypto_list.length()); |
| 1589 | if (DDS::HANDLE_NIL == sending_participant_crypto) { |
| 1590 | // DDS-Security v1.1 8.5.1.9.4 |
| 1591 | // This operation may optionally not perform any transformation of the input RTPS message. |
| 1592 | // In this case, the operation shall return false but not set the exception object. |
| 1593 | return false; |
| 1594 | } |
| 1595 | |
| 1596 | ACE_Guard<ACE_Thread_Mutex> guard(mutex_); |
| 1597 | const KeyTable_t::const_iterator iter = keys_.find(sending_participant_crypto); |
| 1598 | if (iter == keys_.end()) { |
| 1599 | return CommonUtilities::set_security_error(ex, -1, 0, "No entry for sending_participant_crypto"); |
| 1600 | } |
| 1601 | |
| 1602 | const KeySeq& keyseq = iter->second; |
| 1603 | if (!keyseq.length()) { |
| 1604 | return CommonUtilities::set_security_error(ex, -1, 0, "No key for sending_participant_crypto"); |
| 1605 | } |
| 1606 | |
| 1607 | // The input with its RTPS Header changed to an InfoSrc submessage acts as plaintext for encrypt/authenticate |
| 1608 | DDS::OctetSeq transformed(plain_rtps_message.length() + RTPS::SMHDR_SZ); |
| 1609 | transformed.length(transformed.maximum()); |
| 1610 | transformed[0] = RTPS::INFO_SRC; |
| 1611 | transformed[1] = 0; // flags: big-endian |
| 1612 | transformed[2] = 0; // high byte of octetsToNextHeader |
| 1613 | transformed[3] = RTPS::INFO_SRC_SZ; |
| 1614 | std::memcpy(transformed.get_buffer() + RTPS::SMHDR_SZ, plain_rtps_message.get_buffer(), plain_rtps_message.length()); |
| 1615 | |
| 1616 | bool ok, addSecBody = false; |
| 1617 | CryptoHeader cryptoHdr; |
| 1618 | CryptoFooter cryptoFooter; |
| 1619 | DDS::OctetSeq out; |
| 1620 | const DDS::OctetSeq* pOut = &transformed; |
| 1621 | const KeyMaterial& key = keyseq[0]; |
| 1622 | const KeyId_t sKey = std::make_pair(sending_participant_crypto, 0); |
| 1623 | |
| 1624 | if (encrypts(key)) { |
| 1625 | ok = encrypt(key, sessions_[sKey], transformed, cryptoHdr, cryptoFooter, out, ex); |
| 1626 | pOut = &out; |
| 1627 | addSecBody = true; |
| 1628 | |
| 1629 | } else if (authenticates(key)) { |
| 1630 | // the original message's last submsg may have octetsToNextHeader = 0 which |
| 1631 | // isn't valid when appending SEC_POSTFIX, patch in the actual submsg length |
| 1632 | const unsigned int offsetFinal = findLastSubmessage(transformed); |
| 1633 | if (offsetFinal && setOctetsToNextHeader(out, transformed, offsetFinal)) { |
| 1634 | pOut = &out; |
| 1635 | } |
| 1636 | ok = authtag(key, sessions_[sKey], *pOut, cryptoHdr, cryptoFooter, ex); |
| 1637 |
no test coverage detected