• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / github_pull_request_312964

19 Feb 2025 07:31PM UTC coverage: 90.814% (-0.3%) from 91.119%
github_pull_request_312964

Pull #8071

Evergreen

web-flow
Bump serialize-javascript and mocha

Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) to 6.0.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `serialize-javascript` from 6.0.0 to 6.0.2
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2)

Updates `mocha` from 10.2.0 to 10.8.2
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v10.2.0...v10.8.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #8071: Bump serialize-javascript and mocha

96552 of 179126 branches covered (53.9%)

212672 of 234185 relevant lines covered (90.81%)

3115802.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.05
/src/realm/util/sha_crypto.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2019 Realm Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 **************************************************************************/
18

19
#include <realm/util/sha_crypto.hpp>
20
#include <realm/util/backtrace.hpp>
21
#include <realm/util/assert.hpp>
22

23
#if REALM_PLATFORM_APPLE
24
#include <CommonCrypto/CommonCrypto.h>
25
#elif defined(_WIN32)
26
#include <windows.h>
27
#include <stdio.h>
28
#include <bcrypt.h>
29
#pragma comment(lib, "bcrypt.lib")
30
#define REALM_USE_BUNDLED_SHA2 1
31
#elif !REALM_HAVE_OPENSSL
32
#include <sha1.h>
33
#define REALM_USE_BUNDLED_SHA2 1
34
#endif
35

36
/*
37
 * OpenSSL can be used with Windows. If this is the case:
38
 * The Sha-1 & Sha-2 submodules are no longer needed, so the
39
 * REALM_USE_BUNDLED_SHA2 macro should be undefined.
40
 * This is particularly relevant when integrating realm-core
41
 * via vcpkg.
42
 */
43
#if REALM_HAVE_OPENSSL
44
#include <openssl/sha.h>
45
#include <openssl/evp.h>
46
#include <openssl/hmac.h>
47
#undef REALM_USE_BUNDLED_SHA2
48
#endif
49

50
#ifdef REALM_USE_BUNDLED_SHA2
51
#include <sha224.hpp>
52
#include <sha256.hpp>
53
#include <cstring>
54
#endif
55

56
namespace {
57

58
// The message digest of the input is calculated. The output is placed in
59
// out_buffer, and the size of the output is placed in out_size. The caller
60
// guarantees that out_buffer is large enough, which is always possible for
61
// message digests with a maximum output size.
62
#if REALM_PLATFORM_APPLE
63
#elif defined(_WIN32)
64
struct Algorithm {
65
    Algorithm(LPCWSTR alg_id)
66
    {
67
        if (BCryptOpenAlgorithmProvider(&hAlg, alg_id, NULL, 0) < 0) {
68
            throw realm::util::runtime_error("BCryptOpenAlgorithmProvider() failed");
69
        }
70
    }
71
    ~Algorithm()
72
    {
73
        if (hAlg) {
74
            BCryptCloseAlgorithmProvider(hAlg, 0);
75
        }
76
    }
77
    DWORD obj_length()
78
    {
79
        DWORD len;
80
        ULONG dummy;
81
        BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&len, sizeof(DWORD), &dummy, 0);
82
        return len;
83
    }
84
    DWORD hash_length()
85
    {
86
        DWORD len;
87
        ULONG dummy;
88
        BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&len, sizeof(DWORD), &dummy, 0);
89
        return len;
90
    }
91

92
    BCRYPT_ALG_HANDLE hAlg = NULL;
93
};
94
struct Hash {
95
    Hash(Algorithm& a, DWORD output_size)
96
        : alg(a)
97
        , hash_size(output_size)
98
    {
99
        REALM_ASSERT(alg.obj_length() < 512);
100
        REALM_ASSERT(alg.hash_length() == hash_size);
101
        if (BCryptCreateHash(alg.hAlg, &hHash, hash_object_buffer, 515, NULL, 0, 0) < 0) {
102
            throw realm::util::runtime_error("BCryptCreateHash() failed");
103
        }
104
    }
105
    ~Hash()
106
    {
107
        if (hHash) {
108
            BCryptDestroyHash(hHash);
109
        }
110
    }
111
    void get_hash(PUCHAR in_buffer, DWORD in_buffer_size, PUCHAR out_buffer)
112
    {
113
        if (BCryptHashData(hHash, in_buffer, in_buffer_size, 0) < 0) {
114
            throw realm::util::runtime_error("BCryptHashData() failed");
115
        }
116

117
        BCryptFinishHash(hHash, out_buffer, hash_size, 0);
118
    }
119
    Algorithm& alg;
120
    BCRYPT_HASH_HANDLE hHash = NULL;
121
    UCHAR hash_object_buffer[512];
122
    DWORD hash_size;
123
};
124
#elif REALM_HAVE_OPENSSL
125
void message_digest(const EVP_MD* digest_type, const char* in_buffer, size_t in_buffer_size,
126
                    unsigned char* out_buffer, unsigned int* output_size)
127
{
37,311✔
128
    EVP_MD_CTX* ctx = EVP_MD_CTX_create();
37,311✔
129

130
    int rc = EVP_DigestInit_ex(ctx, digest_type, nullptr);
37,311✔
131
    if (rc == 0) {
37,311✔
132
        EVP_MD_CTX_destroy(ctx);
×
133
        throw realm::util::runtime_error("EVP_DigestInit() failed");
×
134
    }
×
135

136
    rc = EVP_DigestUpdate(ctx, in_buffer, in_buffer_size);
37,311✔
137
    if (rc == 0) {
37,311✔
138
        EVP_MD_CTX_destroy(ctx);
×
139
        throw realm::util::runtime_error("EVP_DigestUpdate() failed");
×
140
    }
×
141

142
    rc = EVP_DigestFinal_ex(ctx, out_buffer, output_size);
37,311✔
143

144
    EVP_MD_CTX_destroy(ctx);
37,311✔
145

146
    if (rc == 0)
37,311✔
147
        throw realm::util::runtime_error("EVP_DigestFinal_ex() failed");
×
148
}
37,311✔
149
#endif
150

151
#ifdef REALM_USE_BUNDLED_SHA2
152
using namespace realm::util;
153
template <typename ShaState, size_t digest_length>
154
void hmac(Span<const uint8_t> in_buffer, Span<uint8_t, digest_length> out_buffer, Span<const uint8_t, 32> key)
155
{
156
    uint8_t ipad[64];
157
    for (size_t i = 0; i < 32; ++i)
158
        ipad[i] = key[i] ^ 0x36;
159
    memset(ipad + 32, 0x36, 32);
160

161
    uint8_t opad[64] = {0};
162
    for (size_t i = 0; i < 32; ++i)
163
        opad[i] = key[i] ^ 0x5C;
164
    memset(opad + 32, 0x5C, 32);
165

166
    // Full hmac operation is sha_alg(opad + sha_alg(ipad + data))
167
    ShaState s;
168
    sha_init(s);
169
    sha_process(s, ipad, 64);
170
    sha_process(s, in_buffer.data(), std::uint32_t(in_buffer.size()));
171
    sha_done(s, out_buffer.data());
172

173
    sha_init(s);
174
    sha_process(s, opad, 64);
175
    sha_process(s, out_buffer.data(), std::uint32_t(digest_length));
176
    sha_done(s, out_buffer.data());
177
}
178
#endif
179
} // namespace
180

181
namespace realm {
182
namespace util {
183

184
void sha1(const char* in_buffer, size_t in_buffer_size, unsigned char* out_buffer)
185
{
37,143✔
186
#if REALM_PLATFORM_APPLE
187
    CC_SHA1(in_buffer, CC_LONG(in_buffer_size), out_buffer);
188
#elif defined(_WIN32)
189
    Algorithm alg(BCRYPT_SHA1_ALGORITHM);
190
    Hash hash(alg, 20);
191
    hash.get_hash(reinterpret_cast<PUCHAR>(const_cast<char*>(in_buffer)), DWORD(in_buffer_size), out_buffer);
192
#elif REALM_HAVE_OPENSSL
193
    const EVP_MD* digest_type = EVP_sha1();
194
    unsigned int output_size;
37,143✔
195
    message_digest(digest_type, in_buffer, in_buffer_size, out_buffer, &output_size);
37,143✔
196
    REALM_ASSERT(output_size == 20);
37,143✔
197
#else
198
    SHA1(reinterpret_cast<char*>(out_buffer), in_buffer, in_buffer_size);
199
#endif
200
}
37,143✔
201

202
void sha256(const char* in_buffer, size_t in_buffer_size, unsigned char* out_buffer)
203
{
168✔
204
#if REALM_PLATFORM_APPLE
205
    CC_SHA256(in_buffer, CC_LONG(in_buffer_size), out_buffer);
206
#elif defined(_WIN32)
207
    Algorithm alg(BCRYPT_SHA256_ALGORITHM);
208
    Hash hash(alg, 32);
209
    hash.get_hash(reinterpret_cast<PUCHAR>(const_cast<char*>(in_buffer)), DWORD(in_buffer_size), out_buffer);
210
#elif REALM_HAVE_OPENSSL
211
    const EVP_MD* digest_type = EVP_sha256();
212
    unsigned int output_size;
168✔
213
    message_digest(digest_type, in_buffer, in_buffer_size, out_buffer, &output_size);
168✔
214
    REALM_ASSERT(output_size == 32);
168✔
215
#else
216
    sha256_state s;
217
    sha_init(s);
218
    sha_process(s, in_buffer, uint32_t(in_buffer_size));
219
    sha_done(s, out_buffer);
220
#endif
221
}
168✔
222

223
void hmac_sha224(Span<const uint8_t> in_buffer, Span<uint8_t, 28> out_buffer, Span<const uint8_t, 32> key)
224
{
483,624✔
225
#if REALM_PLATFORM_APPLE
226
    static_assert(CC_SHA224_DIGEST_LENGTH == out_buffer.size());
227
    CCHmac(kCCHmacAlgSHA224, key.data(), key.size(), in_buffer.data(), in_buffer.size(), out_buffer.data());
228
#elif defined(REALM_USE_BUNDLED_SHA2)
229
    static_assert(28 == out_buffer.size());
230
    hmac<sha224_state>(in_buffer, out_buffer, key);
231
#elif REALM_HAVE_OPENSSL
232
    static_assert(SHA224_DIGEST_LENGTH == out_buffer.size());
233
    unsigned int hashLen;
483,624✔
234
    HMAC(EVP_sha224(), key.data(), static_cast<int>(key.size()), in_buffer.data(), in_buffer.size(),
483,624✔
235
         out_buffer.data(), &hashLen);
483,624✔
236
    REALM_ASSERT_DEBUG(hashLen == out_buffer.size());
483,624✔
237
#else
238
#error "No SHA224 digest implementation on this platform."
239
#endif
240
}
483,624✔
241

242
void hmac_sha256(Span<const uint8_t> in_buffer, Span<uint8_t, 32> out_buffer, Span<const uint8_t, 32> key)
243
{
3✔
244
#if REALM_PLATFORM_APPLE
245
    static_assert(CC_SHA256_DIGEST_LENGTH == out_buffer.size());
246
    CCHmac(kCCHmacAlgSHA256, key.data(), key.size(), in_buffer.data(), in_buffer.size(), out_buffer.data());
247
#elif defined(REALM_USE_BUNDLED_SHA2)
248
    static_assert(32 == out_buffer.size());
249
    hmac<sha256_state>(in_buffer, out_buffer, key);
250
#elif REALM_HAVE_OPENSSL
251
    static_assert(SHA256_DIGEST_LENGTH == out_buffer.size());
252
    unsigned int hashLen;
3✔
253
    HMAC(EVP_sha256(), key.data(), static_cast<int>(key.size()), in_buffer.data(), in_buffer.size(),
3✔
254
         out_buffer.data(), &hashLen);
3✔
255
    REALM_ASSERT_DEBUG(hashLen == out_buffer.size());
3✔
256
#else
257
#error "No SHA56 digest implementation on this platform."
258
#endif
259
}
3✔
260

261
} // namespace util
262
} // namespace realm
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc