feat generate sign data
This commit is contained in:
parent
db52928975
commit
a445cdfbec
@ -41,23 +41,29 @@ include(GenerateExportHeader)
|
||||
|
||||
# media-server ps dec enc
|
||||
set(MediaServer_Root ${SecMedia_Root}/3rdpart/media-server)
|
||||
include_directories(${MediaServer_Root}/librtp/include)
|
||||
include_directories(${MediaServer_Root}/libmpeg/include)
|
||||
include_directories(${MediaServer_Root}/libmpeg/source)
|
||||
|
||||
add_library(rtp STATIC "")
|
||||
aux_source_directory(${MediaServer_Root}/libmpeg/include src_rtp)
|
||||
aux_source_directory(${MediaServer_Root}/libmpeg/source src_rtp)
|
||||
aux_source_directory(${MediaServer_Root}/librtp/include src_rtp)
|
||||
aux_source_directory(${MediaServer_Root}/librtp/source src_rtp)
|
||||
aux_source_directory(${MediaServer_Root}/librtp/payload src_rtp)
|
||||
add_library(rtp STATIC ${src_rtp})
|
||||
target_sources(rtp PRIVATE ${src_rtp})
|
||||
foreach(src ${src_rtp})
|
||||
message(STATUS "rtp src: ${src}")
|
||||
endforeach()
|
||||
|
||||
target_include_directories(rtp PUBLIC
|
||||
${MediaServer_Root}/librtp/include
|
||||
${MediaServer_Root}/libmpeg/include
|
||||
${MediaServer_Root}/libmpeg/source)
|
||||
|
||||
include_directories(${SecMedia_Root}/SVAC/src/svac_src)
|
||||
# 添加svac解密
|
||||
aux_source_directory(${SecMedia_Root}/SVAC/src/sm2sm3 src_DEC)
|
||||
aux_source_directory(${SecMedia_Root}/SVAC/src/svac_src src_DEC)
|
||||
add_library(SVAC_DEC STATIC ${src_DEC})
|
||||
# 添加svac加密 include_directories(${DEC_ENC_Algorithm}/SVAC/svac_enc) file(GLOB
|
||||
# 添加svac加密 include_directories(${DEC_ENC_Algoruithm}/SVAC/svac_enc) file(GLOB
|
||||
# src_DEC_ENC ${DEC_ENC_Algorithm}/SVAC/svac_enc/*/*.c
|
||||
# ${DEC_ENC_Algorithm}/SVAC/svac_enc/*/*.h)
|
||||
aux_source_directory(${SecMedia_Root}/SVAC/src/sm2sm3_enc src_ENC)
|
||||
@ -76,31 +82,53 @@ include_directories(include src)
|
||||
|
||||
# file(GLOB SecMedia_src_list ${SecMedia_Root}/SVAC/./*.c
|
||||
# ${SecMedia_Root}/SVAC/./*.h)
|
||||
file(
|
||||
GLOB
|
||||
SecMedia_src_list
|
||||
${SecMedia_Root}/*/*.cpp
|
||||
${SecMedia_Root}/*/*.h
|
||||
${SecMedia_Root}/*/*.c
|
||||
${SecMedia_Root}/*/*/*.cpp
|
||||
${SecMedia_Root}/*/*/*.h
|
||||
${SecMedia_Root}/*/*/*.c
|
||||
)
|
||||
|
||||
macro(append_srcs out_var root_dir)
|
||||
file(GLOB_RECURSE srcs ${root_dir}/*.c ${root_dir}/*.cpp)
|
||||
list(APPEND ${out_var} ${srcs})
|
||||
endmacro(append_srcs)
|
||||
|
||||
append_srcs(SecMedia_src_list ${SecMedia_Root}/DecEnc)
|
||||
append_srcs(SecMedia_src_list ${SecMedia_Root}/Decrypt)
|
||||
append_srcs(SecMedia_src_list ${SecMedia_Root}/Encrypt)
|
||||
append_srcs(SecMedia_src_list ${SecMedia_Root}/GB28181)
|
||||
append_srcs(SecMedia_src_list ${SecMedia_Root}/HuaWei)
|
||||
# append_srcs(SecMedia_src_list ${SecMedia_Root}/SVAC)
|
||||
append_srcs(SecMedia_src_list ${SecMedia_Root}/base)
|
||||
|
||||
# message(STATUS "SRCS: ${SecMedia_src_list}")
|
||||
|
||||
# file(
|
||||
# GLOB
|
||||
# SecMedia_src_list
|
||||
# ${SecMedia_Root}/*/*.cpp
|
||||
# ${SecMedia_Root}/*/*.h
|
||||
# ${SecMedia_Root}/*/*.c
|
||||
# ${SecMedia_Root}/*/*/*.cpp
|
||||
# ${SecMedia_Root}/*/*/*.h
|
||||
# ${SecMedia_Root}/*/*/*.c
|
||||
# )
|
||||
file(GLOB SecMedia_api_list ${CMAKE_CURRENT_SOURCE_DIR}/include/common.h)
|
||||
|
||||
# # target_compile_options(${PROJECT_NAME} PRIVATE -fvisibility=hidden)
|
||||
# list(APPEND LINK_LIB_LIST ${LINK_LIB_SVAC_LIST})
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED
|
||||
"src/base/util.cpp"
|
||||
"src/base/rtp_packet.cpp"
|
||||
"src/SVAC/src/sm2sm3/sm3.c"
|
||||
"src/SVAC/src/sm2sm3/sm2.c"
|
||||
${SecMedia_src_list}
|
||||
)
|
||||
add_library(${PROJECT_NAME} SHARED ${SecMedia_src_list})
|
||||
# add_library(${PROJECT_NAME} STATIC ${SecMedia_src_list})
|
||||
target_link_libraries(${PROJECT_NAME} ${LINK_LIB_SVAC_LIST} rtp)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${SecMedia_Root}/.)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${LINK_LIB_SVAC_LIST} rtp)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${SecMedia_Root}
|
||||
${SecMedia_Root}/3rdpart/media-server/libdash/include
|
||||
${SecMedia_Root}/3rdpart/media-server/libflv/include
|
||||
${SecMedia_Root}/3rdpart/media-server/libhls/include
|
||||
${SecMedia_Root}/3rdpart/media-server/libmov/include
|
||||
${SecMedia_Root}/3rdpart/media-server/libmpeg/include
|
||||
${SecMedia_Root}/3rdpart/media-server/librtmp/include
|
||||
${SecMedia_Root}/3rdpart/media-server/librtp/include
|
||||
${SecMedia_Root}/3rdpart/media-server/librtsp/include
|
||||
${SecMedia_Root}/3rdpart/media-server/libsip/include
|
||||
|
||||
)
|
||||
|
||||
# set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}
|
||||
# SOVERSION 1 PUBLIC_HEADER ${SecMedia_api_list} )
|
||||
|
@ -33,7 +33,7 @@ EncrypInit()
|
||||
{
|
||||
// auto Verify_handle=HWVerify_init();
|
||||
|
||||
auto sign_handle = GB28181_stream_init(&sign_info);//HWSign_init(&sign_info);
|
||||
auto sign_handle = HK_stream_init(&sign_info);//HWSign_init(&sign_info);
|
||||
return sign_handle;
|
||||
}
|
||||
|
||||
@ -68,6 +68,12 @@ template<typename T, typename U>
|
||||
timespec
|
||||
TimeDiff(T &&minu, U &&sub)
|
||||
{
|
||||
if (minu.tv_sec < sub.tv_sec) {
|
||||
return {0, 0};
|
||||
} else if (minu.tv_sec == sub.tv_sec && minu.tv_nsec < sub.tv_nsec) {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
timespec deltatime;
|
||||
deltatime.tv_nsec = minu.tv_nsec - sub.tv_nsec;
|
||||
deltatime.tv_sec = minu.tv_sec - sub.tv_sec;
|
||||
@ -75,7 +81,7 @@ TimeDiff(T &&minu, U &&sub)
|
||||
deltatime.tv_nsec += 1000000000;
|
||||
deltatime.tv_sec--;
|
||||
}
|
||||
return move(deltatime);
|
||||
return deltatime;
|
||||
}
|
||||
|
||||
int
|
||||
@ -116,9 +122,12 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str
|
||||
if (sign_handle) {
|
||||
output_thread = std::shared_ptr<std::thread>(new std::thread([&] {
|
||||
while (processing.load(std::memory_order_relaxed)) {
|
||||
int ret =
|
||||
GB28181_stream_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m);
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
int ret = HK_stream_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m);
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
if (ret != 1) { continue; }
|
||||
// WRNGL("HK_stream_out time: %lu ms\n",
|
||||
// std::chrono::duration_cast<std::chrono::microseconds>(end - now).count());
|
||||
processing_cnt.fetch_sub(1);
|
||||
if (append_len == 0) {
|
||||
sendto(socket, sign_out_buf, sign_out_len, 0, (const sockaddr *) &addr, sizeof(addr));
|
||||
@ -127,8 +136,8 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str
|
||||
sendto(socket, sign_out_buf + offset_len, sign_out_len - offset_len, 0, (const sockaddr *) &addr,
|
||||
sizeof(addr));
|
||||
}
|
||||
// GB28181_stream_in(sign_h2,(char*)payload,payload_len,nullptr);
|
||||
// GB28181_stream_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m);
|
||||
// HK_stream_in(sign_h2,(char*)payload,payload_len,nullptr);
|
||||
// HK_stream_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m);
|
||||
}
|
||||
}));
|
||||
}
|
||||
@ -159,7 +168,7 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str
|
||||
if (sign_handle) {
|
||||
auto cnt = processing_cnt.fetch_add(1);
|
||||
// printf("frame processing cnt:%d\n", cnt);
|
||||
GB28181_stream_in(sign_handle, (char *) payload, payload_len, nullptr);
|
||||
HK_stream_in(sign_handle, (char *) payload, payload_len, nullptr);
|
||||
} else {
|
||||
if (sendto(socket, payload, payload_len, 0, (const sockaddr *) &addr, sizeof(addr)) == -1) {
|
||||
printf("send failed : %s\n", strerror(errno));
|
||||
|
@ -26,7 +26,7 @@ API_EXPORT void *HK_stream_init(struct sec_set_info *sign_info);
|
||||
API_EXPORT int HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param);
|
||||
API_EXPORT void HK_stream_release(void *Handle);
|
||||
API_EXPORT int
|
||||
KH_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param);
|
||||
HK_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param);
|
||||
|
||||
API_EXPORT void *GB28181_stream_init(struct sec_set_info *sign_info);
|
||||
API_EXPORT int GB28181_stream_in(void *Handle, const char *buf, const uint32_t len, void *param);
|
||||
|
@ -9,18 +9,18 @@ static std::atomic<int> g_frame_cnt{0};
|
||||
Frame::~Frame() { g_frame_cnt.fetch_sub(1); }
|
||||
|
||||
Frame::Ptr
|
||||
Frame::CreateUDPFrame(const uint8_t *data, size_t len)
|
||||
Frame::CreateUDPFrame(const void *data, size_t len)
|
||||
{
|
||||
return std::shared_ptr<Frame>(new Frame(kUDP, data, len));
|
||||
}
|
||||
|
||||
Frame::Ptr
|
||||
Frame::CreateTCPFrame(const uint8_t *data, size_t len)
|
||||
Frame::CreateTCPFrame(const void *data, size_t len)
|
||||
{
|
||||
return std::shared_ptr<Frame>(new Frame(kTCP, data, len));
|
||||
}
|
||||
|
||||
Frame::Frame(Type type, const uint8_t *data, size_t len) : _type(type), _data(data, data + len)
|
||||
Frame::Frame(Type type, const void *data, size_t len) : _type(type), _data((uint8_t *) data, (uint8_t *) data + len)
|
||||
{
|
||||
auto cur = g_frame_cnt.fetch_add(1);
|
||||
// INFOL("frame count: %d\n", cur);
|
||||
|
@ -13,8 +13,8 @@ public:
|
||||
|
||||
enum Type { kTCP, kUDP };
|
||||
|
||||
static Ptr CreateUDPFrame(const uint8_t *data, size_t len);
|
||||
static Ptr CreateTCPFrame(const uint8_t *data, size_t len);
|
||||
static Ptr CreateUDPFrame(const void *data, size_t len);
|
||||
static Ptr CreateTCPFrame(const void *data, size_t len);
|
||||
|
||||
public:
|
||||
~Frame();
|
||||
@ -40,7 +40,7 @@ public:
|
||||
void Wait() { _event.Wait(); }
|
||||
|
||||
private:
|
||||
Frame(Type type, const uint8_t *data, size_t len);
|
||||
Frame(Type type, const void *data, size_t len);
|
||||
|
||||
private:
|
||||
Event _event{true};
|
||||
|
@ -7,6 +7,12 @@ FrameManager::FrameManager() { Init(); }
|
||||
|
||||
FrameManager::~FrameManager() {}
|
||||
|
||||
bool
|
||||
FrameManager::Initialize()
|
||||
{
|
||||
return _rtp_manager.Initialize();
|
||||
}
|
||||
|
||||
bool
|
||||
FrameManager::Enqueue(Frame::Ptr frame)
|
||||
{
|
||||
@ -21,6 +27,7 @@ Frame::Ptr
|
||||
FrameManager::Dequeue()
|
||||
{
|
||||
Frame::Ptr frame{nullptr};
|
||||
auto start = std::chrono::system_clock::now();
|
||||
{
|
||||
std::lock_guard<std::mutex> _(_frame_queue_lock);
|
||||
if (_frame_queue.empty()) { return nullptr; }
|
||||
@ -30,6 +37,8 @@ FrameManager::Dequeue()
|
||||
}
|
||||
|
||||
frame->Wait();
|
||||
auto end = std::chrono::system_clock::now();
|
||||
// WRNGL("frame wait time: %ld ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
|
||||
FrameManager();
|
||||
~FrameManager();
|
||||
bool Initialize();
|
||||
|
||||
bool Enqueue(Frame::Ptr frame);
|
||||
Frame::Ptr Dequeue();
|
||||
|
44
src/base/hk_sign.cpp
Normal file
44
src/base/hk_sign.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "HuaWei/HWsign.h"
|
||||
#include "base/frame_manager.h"
|
||||
|
||||
void *
|
||||
HK_stream_init(struct sec_set_info *sign_info)
|
||||
{
|
||||
sign::FrameManager *fm = new sign::FrameManager();
|
||||
fm->SetSecSetInfo(sign_info);
|
||||
if (!fm->Initialize()) {
|
||||
delete fm;
|
||||
return nullptr;
|
||||
}
|
||||
return fm;
|
||||
}
|
||||
|
||||
int
|
||||
HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param)
|
||||
{
|
||||
sign::FrameManager *fm = (sign::FrameManager *) Handle;
|
||||
auto frame = sign::Frame::CreateUDPFrame(buf, len);
|
||||
fm->Enqueue(frame);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
HK_stream_release(void *Handle)
|
||||
{
|
||||
if (Handle) { delete (sign::FrameManager *) Handle; }
|
||||
}
|
||||
|
||||
int
|
||||
HK_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param)
|
||||
{
|
||||
sign::FrameManager *fm = (sign::FrameManager *) Handle;
|
||||
auto frame = fm->Dequeue();
|
||||
if (!frame) { return -1; }
|
||||
|
||||
*len = frame->size();
|
||||
if (buf) { std::copy(frame->data(), frame->data() + frame->size(), buf); }
|
||||
*sei_end_offset = 0;
|
||||
*append_length = 0;
|
||||
|
||||
return 1;
|
||||
}
|
@ -43,7 +43,9 @@ RTPDecoder::Input(RTPPacket::Ptr packet)
|
||||
const uint16_t seq = GetRTPSequenceNumber(packet->packet_data());
|
||||
if (_prev_seq == -1) {
|
||||
_prev_seq = seq;
|
||||
_start_decode_tp = std::chrono::steady_clock::now();
|
||||
} else if (seq != ((_prev_seq + 1) & 0xFFFF)) {
|
||||
_start_decode_tp = std::chrono::steady_clock::now();
|
||||
_ref_rtp_packets.clear();
|
||||
_prev_seq = -1;
|
||||
return;
|
||||
@ -87,7 +89,11 @@ RTPDecoder::CreateHandler()
|
||||
DecodedPacket dp{packet, bytes, timestamp, flags};
|
||||
dp.ref_rtp_packets.swap(self->_ref_rtp_packets);
|
||||
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
// WRNGL("decode time: %lu ms\n",
|
||||
// std::chrono::duration_cast<std::chrono::milliseconds>(end - self->_start_decode_tp).count());
|
||||
self->OnDecoded(dp);
|
||||
self->_start_decode_tp = std::chrono::steady_clock::now();
|
||||
};
|
||||
return handler;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ private:
|
||||
std::vector<uint8_t> _buffer;
|
||||
|
||||
std::vector<RTPPacket::Ptr> _ref_rtp_packets;
|
||||
std::chrono::steady_clock::time_point _start_decode_tp;
|
||||
};
|
||||
}// namespace sign
|
||||
|
||||
|
@ -8,6 +8,13 @@ RTPManager::RTPManager() {}
|
||||
|
||||
RTPManager::~RTPManager() {}
|
||||
|
||||
bool
|
||||
RTPManager::Initialize()
|
||||
{
|
||||
_signer.OnSigned.connect(this, &RTPManager::OnSigned);
|
||||
return _signer.Start(_sec_set_info);
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::OnFrameEnqueue(Frame::Ptr frame)
|
||||
{
|
||||
@ -22,7 +29,46 @@ RTPManager::OnFrameEnqueue(Frame::Ptr frame)
|
||||
|
||||
void
|
||||
RTPManager::SetSecSetInfo(sec_set_info *info)
|
||||
{}
|
||||
{
|
||||
_sec_set_info = info;
|
||||
InitSecSet(info);
|
||||
InitVerifySet(info);
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::InitSecSet(void *data)
|
||||
{
|
||||
sec_set_info *info = (sec_set_info *) data;
|
||||
|
||||
uint8_t security_set_version[19] = "Ver 0.0.2";
|
||||
memset(&_sec_set, 0, sizeof(_sec_set));
|
||||
memset(&_sec_set.evek, 0xFF, sizeof(_sec_set.evek));
|
||||
memset(&_sec_set.iv, 0xFF, sizeof(_sec_set.iv));
|
||||
// Set Flag
|
||||
_sec_set.Flag.encryption_flag = 0;
|
||||
_sec_set.Flag.authnetication_flag = 1;
|
||||
_sec_set.Flag.vek_flag = 0;
|
||||
_sec_set.Flag.iv_flag = 0;
|
||||
_sec_set.Flag.hash_discard_p_picture = 1;
|
||||
_sec_set.Flag.reserved_flag = 0b001;
|
||||
// set Type
|
||||
_sec_set.Type.signature_type = (uint8_t) SecMedia::DecryptType::SM2_auth;
|
||||
_sec_set.Type.hash_type = (uint8_t) SecMedia::DecryptType::SM3;
|
||||
_sec_set.Type.encryption_type = (uint8_t) SecMedia::DecryptType::NONE;
|
||||
_sec_set.Type.vek_encryption_type = (uint8_t) SecMedia::DecryptType::NONE;
|
||||
memcpy(_sec_set.camera_id, info->camera_id, sizeof(_sec_set.camera_id));
|
||||
memcpy(_sec_set.vkek_version, info->vkek_version, sizeof(_sec_set.vkek_version));
|
||||
_sec_set.vkek_version_length_minus1 = sizeof(_sec_set.vkek_version) - 1;
|
||||
_sec_set.end_flag = 0x80;
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::InitVerifySet(void *info)
|
||||
{
|
||||
memset(&_verify_set, 0, sizeof(_verify_set));
|
||||
memset(&_verify_set.sign, 0xFF, sizeof(_verify_set.sign));
|
||||
_verify_set.end_flag = 0x80;
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::ProcessUDPFrame(Frame::Ptr frame)
|
||||
@ -124,6 +170,95 @@ RTPManager::OnRTPDecoded(RTPDecoder::DecodedPacket packet)
|
||||
auto str = ss.str();
|
||||
if (!str.empty()) str.pop_back();
|
||||
INFOL("RTP decoded. type=%2d, size=%5u seq=[%s]\n", h264_type, packet.bytes, str.c_str());
|
||||
if (h264_type == H264Nal::NAL_IDR) {
|
||||
// remove old sign
|
||||
ResetSignData();
|
||||
|
||||
Signer::DataPacket::Ptr sign_packet = std::make_shared<Signer::DataPacket>();
|
||||
sign_packet->param.codec_type = h264_type;
|
||||
sign_packet->param.dts = packet.timestamp;
|
||||
sign_packet->param.data_len = packet.bytes;
|
||||
sign_packet->data = std::vector<uint8_t>((uint8_t *) packet.packet, (uint8_t *) packet.packet + packet.bytes);
|
||||
_signer.Enqueue(sign_packet);
|
||||
} else if (h264_type == H264Nal::NAL_SEI) {
|
||||
INFOL("origin SEI data: %s\n", ToHex((const uint8_t *) packet.packet, packet.bytes).c_str());
|
||||
uint8_t buf[4096];
|
||||
uint8_t *ptr = buf;
|
||||
ptr = SecMedia::appendSEIframe(
|
||||
ptr, SEC_SET_PT, (uint8_t *) SecMedia::Sec_set_UUID, (uint8_t *) (&_sec_set), sizeof(_sec_set));
|
||||
|
||||
auto signed_packet = FetchSignData();
|
||||
if (!signed_packet || signed_packet->sign_data.empty()) {
|
||||
|
||||
if (_signer.state() == Signer::kSigning) {
|
||||
WRNGL("Sign data is empty. still signing\n");
|
||||
_verify_set.head_frame_type = SecMedia::ERR_incomplete_Sign;
|
||||
} else if (!signed_packet) {
|
||||
WRNGL("Sign data is empty. no I-Frame\n");
|
||||
_verify_set.head_frame_type = SecMedia::ERR_Without_Frame_Data;
|
||||
} else {
|
||||
WRNGL("Sign data is empty. no sign_data\n");
|
||||
_verify_set.head_frame_type = SecMedia::ERR_Without_Sign_Data;
|
||||
}
|
||||
|
||||
ptr = SecMedia::appendSEIframe(
|
||||
ptr, VER_SET_PT, (uint8_t *) SecMedia::Ver_set_UUID, (uint8_t *) &_verify_set, sizeof(_verify_set));
|
||||
} else {
|
||||
INFOL("Sign data size=%lu\n", signed_packet->sign_data.size());
|
||||
INFOL("Sign data: %s\n", ToHex(signed_packet->sign_data).c_str());
|
||||
_verify_set.head_frame_type = signed_packet->param.codec_type;
|
||||
_verify_set.head_frame_dts = signed_packet->param.dts;
|
||||
_verify_set.total_hash_data_len = signed_packet->param.data_len;
|
||||
_verify_set.sign_len = signed_packet->sign_data.size();
|
||||
memcpy(_verify_set.sign, signed_packet->sign_data.data(), signed_packet->sign_data.size());
|
||||
|
||||
ptr = SecMedia::appendSEIframe(
|
||||
ptr, VER_SET_PT, (uint8_t *) SecMedia::Ver_set_UUID, (uint8_t *) &_verify_set, sizeof(_verify_set));
|
||||
}
|
||||
ModifySEIPacket(packet, buf, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::ModifySEIPacket(RTPDecoder::DecodedPacket packet, void *sei_begin, void *sei_end)
|
||||
{
|
||||
// TODO: @tqcq 增加对padding udp rtp sei包的处理
|
||||
auto last_packet = packet.ref_rtp_packets.back();
|
||||
auto last_frame = last_packet->ref_frames().back();
|
||||
INFOL("Modify SEI packet. seq=%d, size=%lu\n", last_packet->seq(), last_frame->size());
|
||||
INFOL("SEI data size=%lu\n", (uint8_t *) sei_end - (uint8_t *) sei_begin);
|
||||
INFOL("SEI data: %s\n", ToHex((const uint8_t *) sei_begin, (uint8_t *) sei_end - (uint8_t *) sei_begin).c_str());
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::OnSigned(Signer::SignedPacket::Ptr signed_packet)
|
||||
{
|
||||
INFOL("RTPManager::OnSigned sign data size=%lu\n", signed_packet->sign_data.size());
|
||||
INFOL("RTPManager::OnSigned sign data: %s\n", ToHex(signed_packet->sign_data).c_str());
|
||||
SetSignData(signed_packet);
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::SetSignData(Signer::SignedPacket::Ptr signed_packet)
|
||||
{
|
||||
std::lock_guard<std::mutex> _(_signed_packet_lock);
|
||||
_signed_packet = signed_packet;
|
||||
}
|
||||
|
||||
void
|
||||
RTPManager::ResetSignData()
|
||||
{
|
||||
std::lock_guard<std::mutex> _(_signed_packet_lock);
|
||||
_signed_packet = nullptr;
|
||||
}
|
||||
|
||||
Signer::SignedPacket::Ptr
|
||||
RTPManager::FetchSignData()
|
||||
{
|
||||
std::lock_guard<std::mutex> _(_signed_packet_lock);
|
||||
auto res = _signed_packet;
|
||||
_signed_packet.reset();
|
||||
return res;
|
||||
}
|
||||
|
||||
}// namespace sign
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "HuaWei/HWsign.h"
|
||||
#include "rtp_decoder.h"
|
||||
#include "rtp_packet.h"
|
||||
#include "signer.h"
|
||||
#include "sigslot.h"
|
||||
|
||||
namespace sign {
|
||||
@ -17,12 +18,16 @@ public:
|
||||
RTPManager();
|
||||
~RTPManager();
|
||||
|
||||
bool Initialize();
|
||||
void OnFrameEnqueue(Frame::Ptr frame);
|
||||
|
||||
// HACK:
|
||||
void SetSecSetInfo(sec_set_info *info);
|
||||
|
||||
private:
|
||||
void InitSecSet(void *info);
|
||||
void InitVerifySet(void *info);
|
||||
|
||||
void ProcessUDPFrame(Frame::Ptr);
|
||||
void ProcessTCPFrame(Frame::Ptr);
|
||||
|
||||
@ -37,10 +42,19 @@ private:
|
||||
void IncCurSeq();
|
||||
uint16_t GetNextSeq();
|
||||
|
||||
void SetSignData(Signer::SignedPacket::Ptr signed_packet);
|
||||
void ResetSignData();
|
||||
Signer::SignedPacket::Ptr FetchSignData();
|
||||
|
||||
void ModifySEIPacket(RTPDecoder::DecodedPacket packet, void *sei_begin, void *sei_end);
|
||||
|
||||
private:
|
||||
// FOR TEST
|
||||
// NALU 组包回调
|
||||
void OnRTPDecoded(RTPDecoder::DecodedPacket packet);
|
||||
|
||||
// 签名数据回调
|
||||
void OnSigned(Signer::SignedPacket::Ptr signed_packet);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Partical RTP packet -> Complete RTP packet -> Decoder -> Signer
|
||||
@ -50,6 +64,10 @@ private:
|
||||
* 2. Insert SEI
|
||||
**/
|
||||
|
||||
std::mutex _signed_packet_lock;
|
||||
// std::vector<uint8_t> _sign_data;
|
||||
Signer::SignedPacket::Ptr _signed_packet{nullptr};
|
||||
|
||||
// 当前不完整的RTP包
|
||||
RTPPacket::Ptr _cur_rtp_packet{nullptr};
|
||||
int64_t _cur_rtp_seq{-1};
|
||||
@ -59,6 +77,14 @@ private:
|
||||
uint16_t _insert_packet_num{0};
|
||||
|
||||
RTPDecoder::Ptr _decoder;
|
||||
|
||||
void *_sec_set_info{nullptr};
|
||||
Signer _signer;
|
||||
|
||||
// 安全相关的辅助信息
|
||||
SecMedia::NALUdecodeInfo _sec_set;
|
||||
// 签名验证信息集合
|
||||
SecMedia::VerificationSet _verify_set;
|
||||
};
|
||||
}// namespace sign
|
||||
|
||||
|
@ -5,6 +5,10 @@
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
extern "C" {
|
||||
#include "rtp-packet.h"
|
||||
}
|
||||
|
||||
namespace sign {
|
||||
static std::atomic<int> g_rtp_packet_cnt{0};
|
||||
|
||||
@ -126,7 +130,17 @@ RTPPacket::RTPPacket(RTPManager *owner, Frame::Ptr udp_frame)
|
||||
_rtp_ptr = udp_frame->data();
|
||||
_state = IsRTPHeader(udp_frame->data(), udp_frame->size()) ? kComplete : kError;
|
||||
|
||||
udp_frame->set_paused(true);
|
||||
udp_frame->set_paused(false);
|
||||
if (_state == kComplete) {
|
||||
rtp_packet_t pkt;
|
||||
if (rtp_packet_deserialize(&pkt, udp_frame->data(), udp_frame->size()) == 0) {
|
||||
_state = kComplete;
|
||||
uint8_t h264_type = ((uint8_t *) pkt.payload)[0] & 0x1F;
|
||||
if (h264_type == H264Nal::NAL_SEI) { udp_frame->set_paused(true); }
|
||||
} else {
|
||||
_state = kError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RTPPacket::RTPPacket(RTPManager *owner) : _owner(owner), _frame_type(Frame::kTCP) { IncRTPPacketCnt(); }
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
bool paused() const;
|
||||
void set_paused(bool paused);
|
||||
|
||||
std::vector<Frame::Ptr> ref_frames() const { return _ref_frames; }
|
||||
|
||||
private:
|
||||
RTPPacket(RTPManager *owner, Frame::Ptr udp_frame);
|
||||
RTPPacket(RTPManager *owner);
|
||||
|
@ -1 +1,117 @@
|
||||
#include "signer.h"
|
||||
#include "HuaWei/HWcommon.h"
|
||||
#include "HuaWei/HWsign.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace sign {
|
||||
Signer::Signer() {}
|
||||
|
||||
Signer::~Signer()
|
||||
{
|
||||
Stop();
|
||||
Join();
|
||||
}
|
||||
|
||||
bool
|
||||
Signer::Start(void *param)
|
||||
{
|
||||
_param = param;
|
||||
if (_sign_thread) {
|
||||
ERROL("sign thread already running\n");
|
||||
assert(false);
|
||||
return true;
|
||||
}
|
||||
if (!_param) {
|
||||
WRNGL("sec_set_info param is null\n");
|
||||
return false;
|
||||
}
|
||||
// 初始化安全相关的辅助信息
|
||||
_sign_thread = std::unique_ptr<std::thread>(new std::thread(&Signer::WorkProc, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Signer::Enqueue(DataPacket::Ptr packet)
|
||||
{
|
||||
std::unique_lock<std::mutex> _(_sign_lock);
|
||||
_data_queue.push(packet);
|
||||
_cv.notify_one();
|
||||
}
|
||||
|
||||
void
|
||||
Signer::WorkProc()
|
||||
{
|
||||
sec_set_info *info = reinterpret_cast<sec_set_info *>(_param);
|
||||
if (info) {
|
||||
cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(info->cpu_core, &mask);
|
||||
if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
|
||||
ERROL("set thread affinity failed, target_cpu = %d\n", info->cpu_core);
|
||||
}
|
||||
}
|
||||
|
||||
DataPacket::Ptr data_packet;
|
||||
while (!_stopped.load(std::memory_order_relaxed)) {
|
||||
{
|
||||
std::unique_lock<std::mutex> _(_sign_lock);
|
||||
_cv.wait(_, [this] { return !_data_queue.empty() || _stopped; });
|
||||
if (_stopped) { return; }
|
||||
|
||||
_state = kSigning;
|
||||
data_packet.swap(_data_queue.front());
|
||||
_data_queue.pop();
|
||||
}
|
||||
std::vector<uint8_t> sign;
|
||||
if (!Sign(data_packet->data, &sign)) {
|
||||
// do nothing
|
||||
ERROL("sign failed\n");
|
||||
} else {
|
||||
auto signed_packet = std::make_shared<SignedPacket>();
|
||||
signed_packet->param = data_packet->param;
|
||||
signed_packet->sign_data = sign;
|
||||
OnSigned(signed_packet);
|
||||
}
|
||||
_state = kIdle;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Signer::Sign(const std::vector<uint8_t> &data, std::vector<uint8_t> *sign)
|
||||
{
|
||||
// 1. sm3 hash
|
||||
std::vector<uint8_t> sm3_hash = SM3Hash(data.data(), data.size());
|
||||
if (sm3_hash.empty() || sm3_hash.size() < 32) {
|
||||
ERROL("sm3 hash failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
sec_set_info *info = reinterpret_cast<sec_set_info *>(_param);
|
||||
uint8_t sm2_sign[128];
|
||||
|
||||
do_sm2_sign((char *) info->prikey, (char *) info->pubkey, (char *) sm3_hash.data(), 32, (char *) sm2_sign);
|
||||
sign->assign(sm2_sign, sm2_sign + 64);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Signer::Stop()
|
||||
{
|
||||
_stopped.store(true);
|
||||
}
|
||||
|
||||
void
|
||||
Signer::Join()
|
||||
{
|
||||
if (_sign_thread && _sign_thread->joinable()) {
|
||||
_sign_thread->joinable();
|
||||
_sign_thread.reset();
|
||||
}
|
||||
}
|
||||
|
||||
}// namespace sign
|
||||
|
@ -3,12 +3,73 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DecEnc/NALUdecode.h"
|
||||
#include "sigslot.h"
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
|
||||
namespace sign {
|
||||
class Signer {
|
||||
public:
|
||||
enum State {
|
||||
kIdle,
|
||||
kSigning,
|
||||
};
|
||||
|
||||
struct SignParam {
|
||||
uint64_t data_len;
|
||||
uint32_t dts;
|
||||
uint8_t codec_type;
|
||||
};
|
||||
|
||||
// 待签名数据包
|
||||
struct DataPacket {
|
||||
SignParam param;
|
||||
std::vector<uint8_t> data;
|
||||
using Ptr = std::shared_ptr<DataPacket>;
|
||||
};
|
||||
|
||||
// 签名数据包
|
||||
struct SignedPacket {
|
||||
SignParam param;
|
||||
std::vector<uint8_t> sign_data;
|
||||
using Ptr = std::shared_ptr<SignedPacket>;
|
||||
};
|
||||
|
||||
sigslot::signal1<SignedPacket::Ptr> OnSigned;
|
||||
|
||||
public:
|
||||
Signer();
|
||||
virtual ~Signer();
|
||||
|
||||
void Enqueue(DataPacket::Ptr packet);
|
||||
|
||||
bool Start(void *param);
|
||||
void Stop();
|
||||
void Join();
|
||||
|
||||
State state() const { return _state; }
|
||||
|
||||
private:
|
||||
void WorkProc();
|
||||
|
||||
bool Sign(const std::vector<uint8_t> &data, std::vector<uint8_t> *sign);
|
||||
|
||||
private:
|
||||
State _state{kIdle};
|
||||
void *_param{nullptr};
|
||||
|
||||
std::atomic<bool> _stopped{false};
|
||||
|
||||
std::unique_ptr<std::thread> _sign_thread{nullptr};
|
||||
|
||||
std::mutex _sign_lock;
|
||||
std::condition_variable _cv;
|
||||
// 存放待签名数据
|
||||
std::queue<DataPacket::Ptr> _data_queue;
|
||||
};
|
||||
}// namespace sign
|
||||
|
||||
|
@ -82,6 +82,12 @@ IsParticalRTPHeader(const uint8_t *data, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
ToHex(std::vector<uint8_t> data)
|
||||
{
|
||||
return ToHex(data.data(), data.size());
|
||||
}
|
||||
|
||||
std::string
|
||||
ToHex(const void *data, size_t len)
|
||||
{
|
||||
|
@ -22,6 +22,7 @@ bool IsRTPHeader(const uint8_t *data, size_t len);
|
||||
bool IsParticalRTPHeader(const uint8_t *data, size_t len);
|
||||
|
||||
std::string ToHex(const void *data, size_t len);
|
||||
std::string ToHex(std::vector<uint8_t> data);
|
||||
|
||||
std::vector<uint8_t> SM3Hash(const void *data, size_t len);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user