1 /*
2 * Copyright (c) 2022 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
16 #include "common/log_wrapper.h"
17 #include "websocket/handshake_helper.h"
18
19 namespace OHOS::ArkCompiler::Toolchain {
20 /* static */
EncodeKey(std::string_view key,unsigned char (& destination)[ENCODED_KEY_LEN+1])21 bool WebSocketKeyEncoder::EncodeKey(std::string_view key, unsigned char (&destination)[ENCODED_KEY_LEN + 1])
22 {
23 std::string buffer(key.size() + WEB_SOCKET_GUID.size(), 0);
24 key.copy(buffer.data(), key.size());
25 WEB_SOCKET_GUID.copy(buffer.data() + key.size(), WEB_SOCKET_GUID.size());
26
27 return EncodeKey(reinterpret_cast<unsigned char *>(buffer.data()), buffer.size(), destination);
28 }
29
30 /* static */
EncodeKey(const unsigned char (& key)[KEY_LENGTH+1],unsigned char (& destination)[ENCODED_KEY_LEN+1])31 bool WebSocketKeyEncoder::EncodeKey(const unsigned char(&key)[KEY_LENGTH + 1],
32 unsigned char (&destination)[ENCODED_KEY_LEN + 1])
33 {
34 constexpr size_t bufferSize = KEY_LENGTH + WEB_SOCKET_GUID.size();
35 unsigned char buffer[bufferSize];
36 auto *guid = std::copy(key, key + KEY_LENGTH, buffer);
37 WEB_SOCKET_GUID.copy(reinterpret_cast<char *>(guid), WEB_SOCKET_GUID.size());
38
39 return EncodeKey(buffer, bufferSize, destination);
40 }
41
42 /* static */
EncodeKey(const unsigned char * source,size_t length,unsigned char (& destination)[ENCODED_KEY_LEN+1])43 bool WebSocketKeyEncoder::EncodeKey(const unsigned char *source, size_t length,
44 unsigned char (&destination)[ENCODED_KEY_LEN + 1])
45 {
46 unsigned char hash[SHA_DIGEST_LENGTH];
47 SHA1(source, length, hash);
48
49 // base64-encoding is done via EVP_EncodeBlock, which writes a null-terminated string.
50 int encodedBytes = EVP_EncodeBlock(destination, hash, SHA_DIGEST_LENGTH);
51 // "EVP_EncodeBlock() returns the number of bytes encoded excluding the NUL terminator."
52 if (encodedBytes != ENCODED_KEY_LEN) {
53 LOGE("EVP_EncodeBlock failed to encode all bytes, encodedBytes = %{public}d", encodedBytes);
54 return false;
55 }
56 return true;
57 }
58 } // namespace OHOS::ArkCompiler::Toolchain
59