mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Backed out changeset 8f7c25b71590 (bug 1641178) for causing GTest failures. CLOSED TREE
This commit is contained in:
parent
fc9a6223a7
commit
22e752e996
@ -7,10 +7,10 @@
|
||||
#ifndef mozilla_dom_quota_IPCStreamCipherStrategy_h
|
||||
#define mozilla_dom_quota_IPCStreamCipherStrategy_h
|
||||
|
||||
#include "mozilla/dom/quota/NSSCipherStrategy.h"
|
||||
#include "mozilla/dom/quota/DummyCipherStrategy.h"
|
||||
|
||||
namespace mozilla::dom::quota {
|
||||
using IPCStreamCipherStrategy = NSSCipherStrategy;
|
||||
using IPCStreamCipherStrategy = DummyCipherStrategy;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,153 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "NSSCipherStrategy.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
|
||||
// NSS includes
|
||||
#include "blapit.h"
|
||||
#include "pk11pub.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "seccomon.h"
|
||||
#include "secmodt.h"
|
||||
|
||||
namespace mozilla::dom::quota {
|
||||
|
||||
static_assert(sizeof(NSSCipherStrategy::KeyType) == 32);
|
||||
static_assert(NSSCipherStrategy::BlockPrefixLength == 32);
|
||||
static_assert(NSSCipherStrategy::BasicBlockSize == 16);
|
||||
|
||||
Result<NSSCipherStrategy::KeyType, nsresult> NSSCipherStrategy::GenerateKey() {
|
||||
const auto slot = UniquePK11SlotInfo{PK11_GetInternalSlot()};
|
||||
if (slot == nullptr) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
const auto symKey = UniquePK11SymKey{PK11_KeyGen(
|
||||
slot.get(), CKM_CHACHA20_KEY_GEN, nullptr, sizeof(KeyType), nullptr)};
|
||||
if (symKey == nullptr) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
if (PK11_ExtractKeyValue(symKey.get()) != SECSuccess) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
// No need to free keyData as it is a buffer managed by symKey.
|
||||
SECItem* keyData = PK11_GetKeyData(symKey.get());
|
||||
if (keyData == nullptr) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
KeyType key;
|
||||
MOZ_RELEASE_ASSERT(keyData->len == key.size());
|
||||
std::copy(keyData->data, keyData->data + key.size(), key.data());
|
||||
return key;
|
||||
}
|
||||
|
||||
nsresult NSSCipherStrategy::Init(const CipherMode aMode,
|
||||
const Span<const uint8_t> aKey,
|
||||
const Span<const uint8_t> aInitialIv) {
|
||||
MOZ_ASSERT_IF(CipherMode::Encrypt == aMode, aInitialIv.Length() == 32);
|
||||
|
||||
mMode.init(aMode);
|
||||
|
||||
mIv.AppendElements(aInitialIv);
|
||||
|
||||
const auto slot = UniquePK11SlotInfo{PK11_GetInternalSlot()};
|
||||
if (slot == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
SECItem keyItem;
|
||||
keyItem.data = const_cast<uint8_t*>(aKey.Elements());
|
||||
keyItem.len = aKey.Length();
|
||||
const auto symKey = UniquePK11SymKey{
|
||||
PK11_ImportSymKey(slot.get(), CKM_CHACHA20_POLY1305, PK11_OriginUnwrap,
|
||||
CKA_ENCRYPT, &keyItem, nullptr)};
|
||||
if (symKey == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
SECItem empty = {siBuffer, nullptr, 0};
|
||||
auto pk11Context = UniquePK11Context{PK11_CreateContextBySymKey(
|
||||
CKM_CHACHA20_POLY1305,
|
||||
CKA_NSS_MESSAGE |
|
||||
(CipherMode::Encrypt == aMode ? CKA_ENCRYPT : CKA_DECRYPT),
|
||||
symKey.get(), &empty)};
|
||||
if (pk11Context == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPK11Context.init(std::move(pk11Context));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NSSCipherStrategy::Cipher(const Span<uint8_t> aIv,
|
||||
const Span<const uint8_t> aIn,
|
||||
const Span<uint8_t> aOut) {
|
||||
if (CipherMode::Encrypt == *mMode) {
|
||||
MOZ_RELEASE_ASSERT(aIv.Length() == mIv.Length());
|
||||
memcpy(aIv.Elements(), mIv.Elements(), aIv.Length());
|
||||
}
|
||||
|
||||
// XXX make tag a separate parameter
|
||||
constexpr size_t tagLen = 16;
|
||||
const auto tag = Span{aIv}.Last(tagLen);
|
||||
// tag is const on decrypt, but returned on encrypt
|
||||
|
||||
const auto iv = Span{aIv}.First(12);
|
||||
MOZ_ASSERT(tag.Length() + iv.Length() <= aIv.Length());
|
||||
|
||||
int outLen;
|
||||
// aIn and aOut may not overlap resp. be the same, so we can't do this
|
||||
// in-place.
|
||||
const SECStatus rv = PK11_AEADOp(
|
||||
mPK11Context->get(), CKG_GENERATE_COUNTER,
|
||||
/* TODO use this for the discriminator */ 0, iv.Elements(), iv.Length(),
|
||||
nullptr, 0, aOut.Elements(), &outLen, aOut.Length(), tag.Elements(),
|
||||
tag.Length(), aIn.Elements(), aIn.Length());
|
||||
|
||||
if (CipherMode::Encrypt == *mMode) {
|
||||
memcpy(mIv.Elements(), aIv.Elements(), aIv.Length());
|
||||
}
|
||||
|
||||
return MapSECStatus(rv);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static std::array<uint8_t, N> MakeRandomData() {
|
||||
std::array<uint8_t, N> res;
|
||||
|
||||
const auto rv = PK11_GenerateRandom(res.data(), res.size());
|
||||
/// XXX Allow return of error code to handle this gracefully.
|
||||
MOZ_RELEASE_ASSERT(rv == SECSuccess);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::array<uint8_t, NSSCipherStrategy::BlockPrefixLength>
|
||||
NSSCipherStrategy::MakeBlockPrefix() {
|
||||
return MakeRandomData<BlockPrefixLength>();
|
||||
}
|
||||
|
||||
Span<const uint8_t> NSSCipherStrategy::SerializeKey(const KeyType& aKey) {
|
||||
return Span(aKey);
|
||||
}
|
||||
|
||||
NSSCipherStrategy::KeyType NSSCipherStrategy::DeserializeKey(
|
||||
const Span<const uint8_t>& aSerializedKey) {
|
||||
KeyType res;
|
||||
MOZ_ASSERT(res.size() == aSerializedKey.size());
|
||||
std::copy(aSerializedKey.cbegin(), aSerializedKey.cend(), res.begin());
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom::quota
|
@ -1,56 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_quota_NSSCipherStrategy_h
|
||||
#define mozilla_dom_quota_NSSCipherStrategy_h
|
||||
|
||||
#include "CipherStrategy.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include "mozilla/InitializedOnce.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "ErrorList.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "ScopedNSSTypes.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace mozilla::dom::quota {
|
||||
|
||||
struct NSSCipherStrategy {
|
||||
// Use numeric literals here to avoid having to include NSS headers here.
|
||||
// static_assert's in the cpp file check their consistency.
|
||||
using KeyType = std::array<uint8_t, 32>;
|
||||
static constexpr size_t BlockPrefixLength = 32;
|
||||
static constexpr size_t BasicBlockSize = 16;
|
||||
|
||||
static Result<KeyType, nsresult> GenerateKey();
|
||||
|
||||
nsresult Init(CipherMode aCipherMode, Span<const uint8_t> aKey,
|
||||
Span<const uint8_t> aInitialIv = Span<const uint8_t>{});
|
||||
|
||||
nsresult Cipher(Span<uint8_t> aIv, Span<const uint8_t> aIn,
|
||||
Span<uint8_t> aOut);
|
||||
|
||||
static std::array<uint8_t, BlockPrefixLength> MakeBlockPrefix();
|
||||
|
||||
static Span<const uint8_t> SerializeKey(const KeyType& aKey);
|
||||
|
||||
static KeyType DeserializeKey(const Span<const uint8_t>& aSerializedKey);
|
||||
|
||||
private:
|
||||
// XXX Remove EarlyDestructible, remove moving of the CipherStrategy.
|
||||
LazyInitializedOnceEarlyDestructible<const CipherMode> mMode;
|
||||
LazyInitializedOnceEarlyDestructible<const UniquePK11Context> mPK11Context;
|
||||
nsTArray<uint8_t> mIv;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom::quota
|
||||
|
||||
#endif
|
@ -40,7 +40,6 @@ EXPORTS.mozilla.dom.quota += [
|
||||
"InitializationTypes.h",
|
||||
"IPCStreamCipherStrategy.h",
|
||||
"MemoryOutputStream.h",
|
||||
"NSSCipherStrategy.h",
|
||||
"OriginMetadata.h",
|
||||
"OriginScope.h",
|
||||
"PersistenceType.h",
|
||||
@ -67,7 +66,6 @@ UNIFIED_SOURCES += [
|
||||
"FileStreams.cpp",
|
||||
"MemoryOutputStream.cpp",
|
||||
"nsIndexedDBProtocolHandler.cpp",
|
||||
"NSSCipherStrategy.cpp",
|
||||
"PersistenceType.cpp",
|
||||
"QuotaCommon.cpp",
|
||||
"QuotaManagerService.cpp",
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/SafeRefPtr.h"
|
||||
@ -31,7 +30,6 @@
|
||||
#include "mozilla/dom/quota/EncryptedBlock.h"
|
||||
#include "mozilla/dom/quota/EncryptingOutputStream_impl.h"
|
||||
#include "mozilla/dom/quota/MemoryOutputStream.h"
|
||||
#include "mozilla/dom/quota/NSSCipherStrategy.h"
|
||||
#include "mozilla/fallible.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsError.h"
|
||||
@ -46,7 +44,6 @@
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nscore.h"
|
||||
#include "nss.h"
|
||||
|
||||
namespace mozilla::dom::quota {
|
||||
|
||||
@ -224,32 +221,11 @@ NS_IMETHODIMP ArrayBufferInputStream::Clone(nsIInputStream** _retval) {
|
||||
}
|
||||
} // namespace mozilla::dom::quota
|
||||
|
||||
namespace mozilla {
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSContext, NSSInitContext,
|
||||
NSS_ShutdownContext);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom::quota;
|
||||
|
||||
class DOM_Quota_EncryptedStream : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase() {
|
||||
// Do this only once, do not tear it down per test case.
|
||||
if (!sNssContext) {
|
||||
sNssContext =
|
||||
NSS_InitContext("", "", "", "", nullptr,
|
||||
NSS_INIT_READONLY | NSS_INIT_NOCERTDB |
|
||||
NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN |
|
||||
NSS_INIT_OPTIMIZESPACE | NSS_INIT_NOROOTINIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void TearDownTestCase() { sNssContext = nullptr; }
|
||||
|
||||
private:
|
||||
inline static ScopedNSSContext sNssContext = ScopedNSSContext{};
|
||||
};
|
||||
|
||||
enum struct FlushMode { AfterEachChunk, Never };
|
||||
@ -446,19 +422,6 @@ static RefPtr<dom::quota::MemoryOutputStream> DoRoundtripTest(
|
||||
return baseOutputStream;
|
||||
}
|
||||
|
||||
TEST_P(ParametrizedCryptTest, NSSCipherStrategy) {
|
||||
using CipherStrategy = NSSCipherStrategy;
|
||||
const TestParams& testParams = GetParam();
|
||||
|
||||
auto keyOrErr = CipherStrategy::GenerateKey();
|
||||
ASSERT_FALSE(keyOrErr.isErr());
|
||||
|
||||
DoRoundtripTest<CipherStrategy>(
|
||||
testParams.DataSize(), testParams.EffectiveWriteChunkSize(),
|
||||
testParams.EffectiveReadChunkSize(), testParams.BlockSize(),
|
||||
keyOrErr.unwrap(), testParams.FlushMode());
|
||||
}
|
||||
|
||||
TEST_P(ParametrizedCryptTest, DummyCipherStrategy_CheckOutput) {
|
||||
using CipherStrategy = DummyCipherStrategy;
|
||||
const TestParams& testParams = GetParam();
|
||||
|
@ -280,7 +280,6 @@ NSSUTIL_Quote
|
||||
#ifdef XP_WIN
|
||||
_NSSUTIL_UTF8ToWide
|
||||
#endif
|
||||
PK11_AEADOp
|
||||
PK11_AlgtagToMechanism
|
||||
PK11_Authenticate
|
||||
PK11_ChangePW
|
||||
|
Loading…
Reference in New Issue
Block a user