Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/security/SRICheck.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "SRICheck.h"
8
9
#include "mozilla/Base64.h"
10
#include "mozilla/LoadTainting.h"
11
#include "mozilla/Logging.h"
12
#include "mozilla/Preferences.h"
13
#include "mozilla/dom/SRILogHelper.h"
14
#include "mozilla/dom/SRIMetadata.h"
15
#include "nsContentUtils.h"
16
#include "nsIChannel.h"
17
#include "nsIConsoleReportCollector.h"
18
#include "nsIProtocolHandler.h"
19
#include "nsIScriptError.h"
20
#include "nsIIncrementalStreamLoader.h"
21
#include "nsIURI.h"
22
#include "nsNetUtil.h"
23
#include "nsWhitespaceTokenizer.h"
24
25
#define SRIVERBOSE(args)                                                       \
26
0
  MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Verbose, args)
27
#define SRILOG(args)                                                           \
28
0
  MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug, args)
29
#define SRIERROR(args)                                                         \
30
  MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Error, args)
31
32
namespace mozilla {
33
namespace dom {
34
35
/**
36
 * Returns whether or not the sub-resource about to be loaded is eligible
37
 * for integrity checks. If it's not, the checks will be skipped and the
38
 * sub-resource will be loaded.
39
 */
40
static nsresult
41
IsEligible(nsIChannel* aChannel, mozilla::LoadTainting aTainting,
42
           const nsACString& aSourceFileURI,
43
           nsIConsoleReportCollector* aReporter)
44
0
{
45
0
  NS_ENSURE_ARG_POINTER(aReporter);
46
0
47
0
  if (!aChannel) {
48
0
    SRILOG(("SRICheck::IsEligible, null channel"));
49
0
    return NS_ERROR_SRI_NOT_ELIGIBLE;
50
0
  }
51
0
52
0
  // Was the sub-resource loaded via CORS?
53
0
  if (aTainting == LoadTainting::CORS) {
54
0
    SRILOG(("SRICheck::IsEligible, CORS mode"));
55
0
    return NS_OK;
56
0
  }
57
0
58
0
  nsCOMPtr<nsIURI> finalURI;
59
0
  nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalURI));
60
0
  NS_ENSURE_SUCCESS(rv, rv);
61
0
  nsCOMPtr<nsIURI> originalURI;
62
0
  rv = aChannel->GetOriginalURI(getter_AddRefs(originalURI));
63
0
  NS_ENSURE_SUCCESS(rv, rv);
64
0
  nsAutoCString requestSpec;
65
0
  rv = originalURI->GetSpec(requestSpec);
66
0
  NS_ENSURE_SUCCESS(rv, rv);
67
0
68
0
  if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) {
69
0
    SRILOG(("SRICheck::IsEligible, requestURI=%s; finalURI=%s",
70
0
            requestSpec.get(),
71
0
            finalURI ? finalURI->GetSpecOrDefault().get() : ""));
72
0
  }
73
0
74
0
  // Is the sub-resource same-origin?
75
0
  if (aTainting == LoadTainting::Basic) {
76
0
    SRILOG(("SRICheck::IsEligible, same-origin"));
77
0
    return NS_OK;
78
0
  }
79
0
  SRILOG(("SRICheck::IsEligible, NOT same origin"));
80
0
81
0
  NS_ConvertUTF8toUTF16 requestSpecUTF16(requestSpec);
82
0
  nsTArray<nsString> params;
83
0
  params.AppendElement(requestSpecUTF16);
84
0
  aReporter->AddConsoleReport(nsIScriptError::errorFlag,
85
0
                              NS_LITERAL_CSTRING("Sub-resource Integrity"),
86
0
                              nsContentUtils::eSECURITY_PROPERTIES,
87
0
                              aSourceFileURI, 0, 0,
88
0
                              NS_LITERAL_CSTRING("IneligibleResource"),
89
0
                              const_cast<const nsTArray<nsString>&>(params));
90
0
  return NS_ERROR_SRI_NOT_ELIGIBLE;
91
0
}
92
93
/* static */ nsresult
94
SRICheck::IntegrityMetadata(const nsAString& aMetadataList,
95
                            const nsACString& aSourceFileURI,
96
                            nsIConsoleReportCollector* aReporter,
97
                            SRIMetadata* outMetadata)
98
0
{
99
0
  NS_ENSURE_ARG_POINTER(outMetadata);
100
0
  NS_ENSURE_ARG_POINTER(aReporter);
101
0
  MOZ_ASSERT(outMetadata->IsEmpty()); // caller must pass empty metadata
102
0
103
0
  if (!Preferences::GetBool("security.sri.enable", false)) {
104
0
    SRILOG(("SRICheck::IntegrityMetadata, sri is disabled (pref)"));
105
0
    return NS_ERROR_SRI_DISABLED;
106
0
  }
107
0
108
0
  // put a reasonable bound on the length of the metadata
109
0
  NS_ConvertUTF16toUTF8 metadataList(aMetadataList);
110
0
  if (metadataList.Length() > SRICheck::MAX_METADATA_LENGTH) {
111
0
    metadataList.Truncate(SRICheck::MAX_METADATA_LENGTH);
112
0
  }
113
0
  SRILOG(("SRICheck::IntegrityMetadata, metadataList=%s", metadataList.get()));
114
0
115
0
  // the integrity attribute is a list of whitespace-separated hashes
116
0
  // and options so we need to look at them one by one and pick the
117
0
  // strongest (valid) one
118
0
  nsCWhitespaceTokenizer tokenizer(metadataList);
119
0
  nsAutoCString token;
120
0
  for (uint32_t i=0; tokenizer.hasMoreTokens() &&
121
0
         i < SRICheck::MAX_METADATA_TOKENS; ++i) {
122
0
    token = tokenizer.nextToken();
123
0
124
0
    SRIMetadata metadata(token);
125
0
    if (metadata.IsMalformed()) {
126
0
      NS_ConvertUTF8toUTF16 tokenUTF16(token);
127
0
      nsTArray<nsString> params;
128
0
      params.AppendElement(tokenUTF16);
129
0
      aReporter->AddConsoleReport(nsIScriptError::warningFlag,
130
0
                                  NS_LITERAL_CSTRING("Sub-resource Integrity"),
131
0
                                  nsContentUtils::eSECURITY_PROPERTIES,
132
0
                                  aSourceFileURI, 0, 0,
133
0
                                  NS_LITERAL_CSTRING("MalformedIntegrityHash"),
134
0
                                  const_cast<const nsTArray<nsString>&>(params));
135
0
    } else if (!metadata.IsAlgorithmSupported()) {
136
0
      nsAutoCString alg;
137
0
      metadata.GetAlgorithm(&alg);
138
0
      NS_ConvertUTF8toUTF16 algUTF16(alg);
139
0
      nsTArray<nsString> params;
140
0
      params.AppendElement(algUTF16);
141
0
      aReporter->AddConsoleReport(nsIScriptError::warningFlag,
142
0
                                  NS_LITERAL_CSTRING("Sub-resource Integrity"),
143
0
                                  nsContentUtils::eSECURITY_PROPERTIES,
144
0
                                  aSourceFileURI, 0, 0,
145
0
                                  NS_LITERAL_CSTRING("UnsupportedHashAlg"),
146
0
                                  const_cast<const nsTArray<nsString>&>(params));
147
0
    }
148
0
149
0
    nsAutoCString alg1, alg2;
150
0
    if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) {
151
0
      outMetadata->GetAlgorithm(&alg1);
152
0
      metadata.GetAlgorithm(&alg2);
153
0
    }
154
0
    if (*outMetadata == metadata) {
155
0
      SRILOG(("SRICheck::IntegrityMetadata, alg '%s' is the same as '%s'",
156
0
              alg1.get(), alg2.get()));
157
0
      *outMetadata += metadata; // add new hash to strongest metadata
158
0
    } else if (*outMetadata < metadata) {
159
0
      SRILOG(("SRICheck::IntegrityMetadata, alg '%s' is weaker than '%s'",
160
0
              alg1.get(), alg2.get()));
161
0
      *outMetadata = metadata; // replace strongest metadata with current
162
0
    }
163
0
  }
164
0
165
0
  outMetadata->mIntegrityString = aMetadataList;
166
0
167
0
  if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) {
168
0
    if (outMetadata->IsValid()) {
169
0
      nsAutoCString alg;
170
0
      outMetadata->GetAlgorithm(&alg);
171
0
      SRILOG(("SRICheck::IntegrityMetadata, using a '%s' hash", alg.get()));
172
0
    } else if (outMetadata->IsEmpty()) {
173
0
      SRILOG(("SRICheck::IntegrityMetadata, no metadata"));
174
0
    } else {
175
0
      SRILOG(("SRICheck::IntegrityMetadata, no valid metadata found"));
176
0
    }
177
0
  }
178
0
  return NS_OK;
179
0
}
180
181
//////////////////////////////////////////////////////////////
182
//
183
//////////////////////////////////////////////////////////////
184
SRICheckDataVerifier::SRICheckDataVerifier(const SRIMetadata& aMetadata,
185
                                           const nsACString& aSourceFileURI,
186
                                           nsIConsoleReportCollector* aReporter)
187
  : mCryptoHash(nullptr)
188
  , mBytesHashed(0)
189
  , mHashLength(0)
190
  , mHashType('\0')
191
  , mInvalidMetadata(false)
192
  , mComplete(false)
193
0
{
194
0
  MOZ_ASSERT(!aMetadata.IsEmpty()); // should be checked by caller
195
0
196
0
  // IntegrityMetadata() checks this and returns "no metadata" if
197
0
  // it's disabled so we should never make it this far
198
0
  MOZ_ASSERT(Preferences::GetBool("security.sri.enable", false));
199
0
  MOZ_ASSERT(aReporter);
200
0
201
0
  if (!aMetadata.IsValid()) {
202
0
    nsTArray<nsString> params;
203
0
    aReporter->AddConsoleReport(nsIScriptError::warningFlag,
204
0
                                NS_LITERAL_CSTRING("Sub-resource Integrity"),
205
0
                                nsContentUtils::eSECURITY_PROPERTIES,
206
0
                                aSourceFileURI, 0, 0,
207
0
                                NS_LITERAL_CSTRING("NoValidMetadata"),
208
0
                                const_cast<const nsTArray<nsString>&>(params));
209
0
    mInvalidMetadata = true;
210
0
    return; // ignore invalid metadata for forward-compatibility
211
0
  }
212
0
213
0
  aMetadata.GetHashType(&mHashType, &mHashLength);
214
0
}
215
216
nsresult
217
SRICheckDataVerifier::EnsureCryptoHash()
218
0
{
219
0
  MOZ_ASSERT(!mInvalidMetadata);
220
0
221
0
  if (mCryptoHash) {
222
0
    return NS_OK;
223
0
  }
224
0
225
0
  nsresult rv;
226
0
  nsCOMPtr<nsICryptoHash> cryptoHash =
227
0
    do_CreateInstance("@mozilla.org/security/hash;1", &rv);
228
0
  NS_ENSURE_SUCCESS(rv, rv);
229
0
  rv = cryptoHash->Init(mHashType);
230
0
  NS_ENSURE_SUCCESS(rv, rv);
231
0
232
0
  mCryptoHash = cryptoHash;
233
0
  return NS_OK;
234
0
}
235
236
nsresult
237
SRICheckDataVerifier::Update(uint32_t aStringLen, const uint8_t* aString)
238
0
{
239
0
  NS_ENSURE_ARG_POINTER(aString);
240
0
  if (mInvalidMetadata) {
241
0
    return NS_OK; // ignoring any data updates, see mInvalidMetadata usage
242
0
  }
243
0
244
0
  nsresult rv;
245
0
  rv = EnsureCryptoHash();
246
0
  NS_ENSURE_SUCCESS(rv, rv);
247
0
248
0
  mBytesHashed += aStringLen;
249
0
250
0
  return mCryptoHash->Update(aString, aStringLen);
251
0
}
252
253
nsresult
254
SRICheckDataVerifier::Finish()
255
0
{
256
0
  if (mInvalidMetadata || mComplete) {
257
0
    return NS_OK; // already finished or invalid metadata
258
0
  }
259
0
260
0
  nsresult rv;
261
0
  rv = EnsureCryptoHash(); // we need computed hash even for 0-length data
262
0
  NS_ENSURE_SUCCESS(rv, rv);
263
0
264
0
  rv = mCryptoHash->Finish(false, mComputedHash);
265
0
  mCryptoHash = nullptr;
266
0
  mComplete = true;
267
0
  return rv;
268
0
}
269
270
nsresult
271
SRICheckDataVerifier::VerifyHash(const SRIMetadata& aMetadata,
272
                                 uint32_t aHashIndex,
273
                                 const nsACString& aSourceFileURI,
274
                                 nsIConsoleReportCollector* aReporter)
275
0
{
276
0
  NS_ENSURE_ARG_POINTER(aReporter);
277
0
278
0
  nsAutoCString base64Hash;
279
0
  aMetadata.GetHash(aHashIndex, &base64Hash);
280
0
  SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u]=%s", aHashIndex, base64Hash.get()));
281
0
282
0
  nsAutoCString binaryHash;
283
0
  if (NS_WARN_IF(NS_FAILED(Base64Decode(base64Hash, binaryHash)))) {
284
0
    nsTArray<nsString> params;
285
0
    aReporter->AddConsoleReport(nsIScriptError::errorFlag,
286
0
                                NS_LITERAL_CSTRING("Sub-resource Integrity"),
287
0
                                nsContentUtils::eSECURITY_PROPERTIES,
288
0
                                aSourceFileURI, 0, 0,
289
0
                                NS_LITERAL_CSTRING("InvalidIntegrityBase64"),
290
0
                                const_cast<const nsTArray<nsString>&>(params));
291
0
    return NS_ERROR_SRI_CORRUPT;
292
0
  }
293
0
294
0
  uint32_t hashLength;
295
0
  int8_t hashType;
296
0
  aMetadata.GetHashType(&hashType, &hashLength);
297
0
  if (binaryHash.Length() != hashLength) {
298
0
    nsTArray<nsString> params;
299
0
    aReporter->AddConsoleReport(nsIScriptError::errorFlag,
300
0
                                NS_LITERAL_CSTRING("Sub-resource Integrity"),
301
0
                                nsContentUtils::eSECURITY_PROPERTIES,
302
0
                                aSourceFileURI, 0, 0,
303
0
                                NS_LITERAL_CSTRING("InvalidIntegrityLength"),
304
0
                                const_cast<const nsTArray<nsString>&>(params));
305
0
    return NS_ERROR_SRI_CORRUPT;
306
0
  }
307
0
308
0
  if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) {
309
0
    nsAutoCString encodedHash;
310
0
    nsresult rv = Base64Encode(mComputedHash, encodedHash);
311
0
    if (NS_SUCCEEDED(rv)) {
312
0
      SRILOG(("SRICheckDataVerifier::VerifyHash, mComputedHash=%s",
313
0
              encodedHash.get()));
314
0
    }
315
0
  }
316
0
317
0
  if (!binaryHash.Equals(mComputedHash)) {
318
0
    SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] did not match", aHashIndex));
319
0
    return NS_ERROR_SRI_CORRUPT;
320
0
  }
321
0
322
0
  SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] verified successfully", aHashIndex));
323
0
  return NS_OK;
324
0
}
325
326
nsresult
327
SRICheckDataVerifier::Verify(const SRIMetadata& aMetadata,
328
                             nsIChannel* aChannel,
329
                             const nsACString& aSourceFileURI,
330
                             nsIConsoleReportCollector* aReporter)
331
0
{
332
0
  NS_ENSURE_ARG_POINTER(aReporter);
333
0
334
0
  if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) {
335
0
    nsAutoCString requestURL;
336
0
    nsCOMPtr<nsIRequest> request;
337
0
    request = do_QueryInterface(aChannel);
338
0
    request->GetName(requestURL);
339
0
    SRILOG(("SRICheckDataVerifier::Verify, url=%s (length=%zu)",
340
0
            requestURL.get(), mBytesHashed));
341
0
  }
342
0
343
0
  nsresult rv = Finish();
344
0
  NS_ENSURE_SUCCESS(rv, rv);
345
0
346
0
  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
347
0
  NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
348
0
  LoadTainting tainting = loadInfo->GetTainting();
349
0
350
0
  if (NS_FAILED(IsEligible(aChannel, tainting, aSourceFileURI, aReporter))) {
351
0
    return NS_ERROR_SRI_NOT_ELIGIBLE;
352
0
  }
353
0
354
0
  if (mInvalidMetadata) {
355
0
    return NS_OK; // ignore invalid metadata for forward-compatibility
356
0
  }
357
0
358
0
  for (uint32_t i = 0; i < aMetadata.HashCount(); i++) {
359
0
    if (NS_SUCCEEDED(VerifyHash(aMetadata, i, aSourceFileURI, aReporter))) {
360
0
      return NS_OK; // stop at the first valid hash
361
0
    }
362
0
  }
363
0
364
0
  nsAutoCString alg;
365
0
  aMetadata.GetAlgorithm(&alg);
366
0
  NS_ConvertUTF8toUTF16 algUTF16(alg);
367
0
  nsTArray<nsString> params;
368
0
  params.AppendElement(algUTF16);
369
0
  aReporter->AddConsoleReport(nsIScriptError::errorFlag,
370
0
                              NS_LITERAL_CSTRING("Sub-resource Integrity"),
371
0
                              nsContentUtils::eSECURITY_PROPERTIES,
372
0
                              aSourceFileURI, 0, 0,
373
0
                              NS_LITERAL_CSTRING("IntegrityMismatch"),
374
0
                              const_cast<const nsTArray<nsString>&>(params));
375
0
  return NS_ERROR_SRI_CORRUPT;
376
0
}
377
378
uint32_t
379
SRICheckDataVerifier::DataSummaryLength()
380
0
{
381
0
  MOZ_ASSERT(!mInvalidMetadata);
382
0
  return sizeof(mHashType) + sizeof(mHashLength) + mHashLength;
383
0
}
384
385
uint32_t
386
SRICheckDataVerifier::EmptyDataSummaryLength()
387
0
{
388
0
  return sizeof(int8_t) + sizeof(uint32_t);
389
0
}
390
391
nsresult
392
SRICheckDataVerifier::DataSummaryLength(uint32_t aDataLen, const uint8_t* aData, uint32_t* length)
393
0
{
394
0
  *length = 0;
395
0
  NS_ENSURE_ARG_POINTER(aData);
396
0
397
0
  // we expect to always encode an SRI, even if it is empty or incomplete
398
0
  if (aDataLen < EmptyDataSummaryLength()) {
399
0
    SRILOG(("SRICheckDataVerifier::DataSummaryLength, encoded length[%u] is too small", aDataLen));
400
0
    return NS_ERROR_SRI_IMPORT;
401
0
  }
402
0
403
0
  // decode the content of the buffer
404
0
  size_t offset = sizeof(mHashType);
405
0
  decltype(mHashLength) len = 0;
406
0
  memcpy(&len, &aData[offset], sizeof(mHashLength));
407
0
  offset += sizeof(mHashLength);
408
0
409
0
  SRIVERBOSE(("SRICheckDataVerifier::DataSummaryLength, header {%x, %x, %x, %x, %x, ...}",
410
0
              aData[0], aData[1], aData[2], aData[3], aData[4]));
411
0
412
0
  if (offset + len > aDataLen) {
413
0
    SRILOG(("SRICheckDataVerifier::DataSummaryLength, encoded length[%u] overflow the buffer size", aDataLen));
414
0
    SRIVERBOSE(("SRICheckDataVerifier::DataSummaryLength, offset[%u], len[%u]",
415
0
                uint32_t(offset), uint32_t(len)));
416
0
    return NS_ERROR_SRI_IMPORT;
417
0
  }
418
0
  *length = uint32_t(offset + len);
419
0
  return NS_OK;
420
0
}
421
422
nsresult
423
SRICheckDataVerifier::ImportDataSummary(uint32_t aDataLen, const uint8_t* aData)
424
0
{
425
0
  MOZ_ASSERT(!mInvalidMetadata); // mHashType and mHashLength should be valid
426
0
  MOZ_ASSERT(!mCryptoHash); // EnsureCryptoHash should not have been called
427
0
  NS_ENSURE_ARG_POINTER(aData);
428
0
  if (mInvalidMetadata) {
429
0
    return NS_OK; // ignoring any data updates, see mInvalidMetadata usage
430
0
  }
431
0
432
0
  // we expect to always encode an SRI, even if it is empty or incomplete
433
0
  if (aDataLen < DataSummaryLength()) {
434
0
    SRILOG(("SRICheckDataVerifier::ImportDataSummary, encoded length[%u] is too small", aDataLen));
435
0
    return NS_ERROR_SRI_IMPORT;
436
0
  }
437
0
438
0
  SRIVERBOSE(("SRICheckDataVerifier::ImportDataSummary, header {%x, %x, %x, %x, %x, ...}",
439
0
              aData[0], aData[1], aData[2], aData[3], aData[4]));
440
0
441
0
  // decode the content of the buffer
442
0
  size_t offset = 0;
443
0
  decltype(mHashType) hashType;
444
0
  memcpy(&hashType, &aData[offset], sizeof(mHashType));
445
0
  if (hashType != mHashType) {
446
0
    SRILOG(("SRICheckDataVerifier::ImportDataSummary, hash type[%d] does not match[%d]",
447
0
            hashType, mHashType));
448
0
    return NS_ERROR_SRI_UNEXPECTED_HASH_TYPE;
449
0
  }
450
0
  offset += sizeof(mHashType);
451
0
452
0
  decltype(mHashLength) hashLength;
453
0
  memcpy(&hashLength, &aData[offset], sizeof(mHashLength));
454
0
  if (hashLength != mHashLength) {
455
0
    SRILOG(("SRICheckDataVerifier::ImportDataSummary, hash length[%d] does not match[%d]",
456
0
            hashLength, mHashLength));
457
0
    return NS_ERROR_SRI_UNEXPECTED_HASH_TYPE;
458
0
  }
459
0
  offset += sizeof(mHashLength);
460
0
461
0
  // copy the hash to mComputedHash, as-if we had finished streaming the bytes
462
0
  mComputedHash.Assign(reinterpret_cast<const char*>(&aData[offset]), mHashLength);
463
0
  mCryptoHash = nullptr;
464
0
  mComplete = true;
465
0
  return NS_OK;
466
0
}
467
468
nsresult
469
SRICheckDataVerifier::ExportDataSummary(uint32_t aDataLen, uint8_t* aData)
470
0
{
471
0
  MOZ_ASSERT(!mInvalidMetadata); // mHashType and mHashLength should be valid
472
0
  MOZ_ASSERT(mComplete); // finished streaming
473
0
  NS_ENSURE_ARG_POINTER(aData);
474
0
  NS_ENSURE_TRUE(aDataLen >= DataSummaryLength(), NS_ERROR_INVALID_ARG);
475
0
476
0
  // serialize the hash in the buffer
477
0
  size_t offset = 0;
478
0
  memcpy(&aData[offset], &mHashType, sizeof(mHashType));
479
0
  offset += sizeof(mHashType);
480
0
  memcpy(&aData[offset], &mHashLength, sizeof(mHashLength));
481
0
  offset += sizeof(mHashLength);
482
0
483
0
  SRIVERBOSE(("SRICheckDataVerifier::ExportDataSummary, header {%x, %x, %x, %x, %x, ...}",
484
0
              aData[0], aData[1], aData[2], aData[3], aData[4]));
485
0
486
0
  // copy the hash to mComputedHash, as-if we had finished streaming the bytes
487
0
  nsCharTraits<char>::copy(reinterpret_cast<char*>(&aData[offset]),
488
0
                           mComputedHash.get(), mHashLength);
489
0
  return NS_OK;
490
0
}
491
492
nsresult
493
SRICheckDataVerifier::ExportEmptyDataSummary(uint32_t aDataLen, uint8_t* aData)
494
0
{
495
0
  NS_ENSURE_ARG_POINTER(aData);
496
0
  NS_ENSURE_TRUE(aDataLen >= EmptyDataSummaryLength(), NS_ERROR_INVALID_ARG);
497
0
498
0
  // serialize an unknown hash in the buffer, to be able to skip it later
499
0
  size_t offset = 0;
500
0
  memset(&aData[offset], 0, sizeof(mHashType));
501
0
  offset += sizeof(mHashType);
502
0
  memset(&aData[offset], 0, sizeof(mHashLength));
503
0
  offset += sizeof(mHashLength);
504
0
505
0
  SRIVERBOSE(("SRICheckDataVerifier::ExportEmptyDataSummary, header {%x, %x, %x, %x, %x, ...}",
506
0
              aData[0], aData[1], aData[2], aData[3], aData[4]));
507
0
508
0
  return NS_OK;
509
0
}
510
511
} // namespace dom
512
} // namespace mozilla