• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "credential_message.h"
16 
17 using namespace Hdc;
18 
CredentialMessage(const std::string & messageStr)19 CredentialMessage::CredentialMessage(const std::string& messageStr)
20 {
21     Init(messageStr);
22 }
23 
Init(const std::string & messageStr)24 void CredentialMessage::Init(const std::string& messageStr)
25 {
26     if (messageStr.empty() || messageStr.length() < MESSAGE_BODY_POS) {
27         WRITE_LOG(LOG_FATAL, "messageStr is too short!");
28         return;
29     }
30 
31     int versionInt = messageStr[MESSAGE_VERSION_POS] - '0';
32     if ((versionInt >= METHOD_VERSION_V1 && versionInt <= METHOD_VERSION_MAX) ? false : true) {
33         WRITE_LOG(LOG_FATAL, "Invalid message version %d.", versionInt);
34         return;
35     }
36 
37     messageVersion = versionInt;
38 
39     std::string messageMethodStr = messageStr.substr(MESSAGE_METHOD_POS, MESSAGE_METHOD_LEN);
40     messageMethodType = StripLeadingZeros(messageMethodStr);
41 
42     std::string messageLengthStr = messageStr.substr(MESSAGE_LENGTH_POS, MESSAGE_LENGTH_LEN);
43     char* end = nullptr;
44     size_t bodyLength = static_cast<size_t>(strtol(messageLengthStr.c_str(), &end, 10));
45     if (end == nullptr || *end != '\0' || bodyLength > MESSAGE_STR_MAX_LEN) {
46         WRITE_LOG(LOG_FATAL, "Invalid message body length %s.", messageLengthStr.c_str());
47         return;
48     }
49 
50     if (messageStr.length() < MESSAGE_BODY_POS + bodyLength) {
51         WRITE_LOG(LOG_FATAL, "messageStr is too short.");
52         return;
53     }
54 
55     messageBodyLen = static_cast<int>(bodyLength);
56     messageBody = messageStr.substr(MESSAGE_BODY_POS, bodyLength);
57 }
~CredentialMessage()58 CredentialMessage::~CredentialMessage()
59 {
60     if (!messageBody.empty()) {
61         memset_s(&messageBody[0], messageBody.size(), 0, messageBody.size());
62     }
63 }
64 
SetMessageVersion(int version)65 void CredentialMessage::SetMessageVersion(int version)
66 {
67     if (version >= METHOD_VERSION_V1 && version <= METHOD_VERSION_MAX) {
68         messageVersion = version;
69     } else {
70         WRITE_LOG(LOG_FATAL, "Invalid message version %d.", version);
71     }
72 }
73 
SetMessageBody(const std::string & body)74 void CredentialMessage::SetMessageBody(const std::string& body)
75 {
76     if (body.size() > MESSAGE_STR_MAX_LEN) {
77         WRITE_LOG(LOG_FATAL, "Message body length exceeds maximum allowed length.");
78         return;
79     }
80     messageBody = body;
81     messageBodyLen = static_cast<int>(messageBody.size());
82 }
83 
Construct() const84 std::string CredentialMessage::Construct() const
85 {
86     size_t totalLength = 0;
87     totalLength += 1;
88     totalLength += MESSAGE_METHOD_LEN;
89     totalLength += MESSAGE_LENGTH_LEN;
90     totalLength += messageBody.size();
91 
92     std::string messageMethodTypeStr = IntToStringWithPadding(messageMethodType, MESSAGE_METHOD_LEN);
93     if (messageMethodTypeStr.size() != MESSAGE_METHOD_LEN) {
94         WRITE_LOG(LOG_FATAL, "messageMethod length Error!");
95         return "";
96     }
97 
98     std::string messageBodyLenStr = IntToStringWithPadding(messageBodyLen, MESSAGE_LENGTH_LEN);
99     if (messageBodyLenStr.empty() || (messageBodyLenStr.size() > MESSAGE_LENGTH_LEN)) {
100         WRITE_LOG(LOG_FATAL, "messageBodyLen length must be:%d,now is:%s",
101             MESSAGE_LENGTH_LEN, messageBodyLenStr.c_str());
102         return "";
103     }
104 
105     std::string result;
106     result.reserve(totalLength);
107     result.push_back('0' + messageVersion);
108     result.append(messageMethodTypeStr);
109     result.append(messageBodyLenStr);
110     result.append(messageBody);
111 
112     if (result.size() != totalLength) {
113         WRITE_LOG(LOG_FATAL, "size mismatch. Expected: %zu, Actual: %zu", totalLength, result.size());
114         return "";
115     }
116 
117     return result;
118 }
119 
IsNumeric(const std::string & str)120 bool IsNumeric(const std::string& str)
121 {
122     if (str.empty()) {
123         return false;
124     }
125     for (char ch : str) {
126         if (!std::isdigit(ch)) {
127             return false;
128         }
129     }
130     return true;
131 }
132 
StripLeadingZeros(const std::string & input)133 int StripLeadingZeros(const std::string& input)
134 {
135     if (input.empty() || input == "0") {
136         return 0;
137     }
138     size_t firstNonZero = input.find_first_not_of('0');
139     if (firstNonZero == std::string::npos) {
140         return 0;
141     }
142 
143     std::string numberStr = input.substr(firstNonZero);
144     if (!IsNumeric(numberStr)) {
145         WRITE_LOG(LOG_FATAL, "StripLeadingZeros: invalid numeric string.");
146         return -1;
147     }
148 
149     char* end = nullptr;
150     long value = strtol(numberStr.c_str(), &end, 10);
151     return static_cast<int>(value);
152 }
153 
String2Uint8(const std::string & str,size_t len)154 std::vector<uint8_t> String2Uint8(const std::string& str, size_t len)
155 {
156     std::vector<uint8_t> byteData(len);
157     for (size_t i = 0; i < len; i++) {
158         byteData[i] = static_cast<uint8_t>(str[i]);
159     }
160     return byteData;
161 }
162 
IntToStringWithPadding(int length,int maxLen)163 std::string IntToStringWithPadding(int length, int maxLen)
164 {
165     std::string str = std::to_string(length);
166     if (str.length() > static_cast<size_t>(maxLen)) {
167         return "";
168     }
169     return std::string(static_cast<size_t>(maxLen) - str.length(), '0') + str;
170 }