mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-06 04:35:04 +00:00
Merge inbound to mozilla-central. a=merge
This commit is contained in:
commit
7bfb685bb2
@ -1023,8 +1023,9 @@ pref("dom.ipc.shims.enabledWarnings", false);
|
||||
// everything, but will probably cause some functionality restrictions
|
||||
pref("dom.ipc.plugins.sandbox-level.default", 0);
|
||||
#if defined(_AMD64_)
|
||||
// The lines in PluginModuleParent.cpp should be changed in line with this.
|
||||
pref("dom.ipc.plugins.sandbox-level.flash", 2);
|
||||
// The base sandbox level in nsPluginTag::InitSandboxLevel must be
|
||||
// updated to keep in sync with this value.
|
||||
pref("dom.ipc.plugins.sandbox-level.flash", 3);
|
||||
#else
|
||||
pref("dom.ipc.plugins.sandbox-level.flash", 0);
|
||||
#endif
|
||||
|
@ -645,6 +645,7 @@ static_assert(sizeof(FragmentOrElement::nsDOMSlots) <= MaxDOMSlotSizeAllowed,
|
||||
void
|
||||
nsIContent::nsExtendedContentSlots::Unlink()
|
||||
{
|
||||
mBindingParent = nullptr;
|
||||
mXBLInsertionPoint = nullptr;
|
||||
mContainingShadow = nullptr;
|
||||
mAssignedSlot = nullptr;
|
||||
@ -653,6 +654,9 @@ nsIContent::nsExtendedContentSlots::Unlink()
|
||||
void
|
||||
nsIContent::nsExtendedContentSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
|
||||
{
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mBindingParent");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mBindingParent));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mContainingShadow");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
||||
|
||||
@ -664,7 +668,6 @@ nsIContent::nsExtendedContentSlots::Traverse(nsCycleCollectionTraversalCallback&
|
||||
}
|
||||
|
||||
nsIContent::nsExtendedContentSlots::nsExtendedContentSlots()
|
||||
: mBindingParent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -736,8 +739,9 @@ FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) c
|
||||
// - mChildrenList
|
||||
// - mClassList
|
||||
|
||||
// The following members are not measured:
|
||||
// - mBindingParent / mControllers: because they're non-owning
|
||||
// The following member are not measured:
|
||||
// - mControllers: because it is non-owning
|
||||
// - mBindingParent: because it is some ancestor element.
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ StructuredCloneBlob::ReadStructuredCloneInternal(JSContext* aCx, JSStructuredClo
|
||||
BlobImpls().AppendElements(&aHolder->BlobImpls()[blobOffset], blobCount);
|
||||
}
|
||||
|
||||
JSStructuredCloneData data;
|
||||
JSStructuredCloneData data(mStructuredCloneScope);
|
||||
while (length) {
|
||||
size_t size;
|
||||
char* buffer = data.AllocateBytes(length, &size);
|
||||
|
@ -874,6 +874,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
|
||||
if (aRetVal) {
|
||||
StructuredCloneData* data = aRetVal->AppendElement();
|
||||
data->InitScope(JS::StructuredCloneScope::DifferentProcess);
|
||||
data->Write(cx, rval, aError);
|
||||
if (NS_WARN_IF(aError.Failed())) {
|
||||
aRetVal->RemoveLastElement();
|
||||
|
@ -451,7 +451,7 @@ public:
|
||||
virtual nsIContent* GetBindingParent() const
|
||||
{
|
||||
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
return slots ? slots->mBindingParent : nullptr;
|
||||
return slots ? slots->mBindingParent.get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -808,7 +808,7 @@ protected:
|
||||
*
|
||||
* @see nsIContent::GetBindingParent
|
||||
*/
|
||||
nsIContent* mBindingParent; // [Weak]
|
||||
nsCOMPtr<nsIContent> mBindingParent;
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetXBLInsertionPoint
|
||||
|
@ -19525,7 +19525,7 @@ UpgradeFileIdsFunction::OnFunctionCall(mozIStorageValueArray* aArguments,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
StructuredCloneReadInfo cloneInfo;
|
||||
StructuredCloneReadInfo cloneInfo(JS::StructuredCloneScope::DifferentProcess);
|
||||
DatabaseOperationBase::GetStructuredCloneReadInfoFromValueArray(aArguments,
|
||||
1,
|
||||
0,
|
||||
@ -25005,7 +25005,7 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
|
||||
}
|
||||
#endif
|
||||
|
||||
StructuredCloneReadInfo cloneInfo;
|
||||
StructuredCloneReadInfo cloneInfo(JS::StructuredCloneScope::DifferentProcess);
|
||||
nsresult rv =
|
||||
GetStructuredCloneReadInfoFromValueArray(aValues,
|
||||
/* aDataIndex */ 3,
|
||||
@ -27703,7 +27703,7 @@ CursorOpBase::PopulateResponseFromStatement(
|
||||
|
||||
switch (mCursor->mType) {
|
||||
case OpenCursorParams::TObjectStoreOpenCursorParams: {
|
||||
StructuredCloneReadInfo cloneInfo;
|
||||
StructuredCloneReadInfo cloneInfo(JS::StructuredCloneScope::DifferentProcess);
|
||||
rv = GetStructuredCloneReadInfoFromStatement(aStmt,
|
||||
2,
|
||||
1,
|
||||
@ -27751,7 +27751,7 @@ CursorOpBase::PopulateResponseFromStatement(
|
||||
return rv;
|
||||
}
|
||||
|
||||
StructuredCloneReadInfo cloneInfo;
|
||||
StructuredCloneReadInfo cloneInfo(JS::StructuredCloneScope::DifferentProcess);
|
||||
rv = GetStructuredCloneReadInfoFromStatement(aStmt,
|
||||
4,
|
||||
3,
|
||||
|
@ -64,6 +64,10 @@ struct StructuredCloneReadInfo
|
||||
IDBDatabase* mDatabase;
|
||||
bool mHasPreprocessInfo;
|
||||
|
||||
// In IndexedDatabaseInlines.h
|
||||
inline explicit
|
||||
StructuredCloneReadInfo(JS::StructuredCloneScope aScope);
|
||||
|
||||
// In IndexedDatabaseInlines.h
|
||||
inline
|
||||
StructuredCloneReadInfo();
|
||||
|
@ -45,13 +45,20 @@ StructuredCloneFile::operator==(const StructuredCloneFile& aOther) const
|
||||
}
|
||||
|
||||
inline
|
||||
StructuredCloneReadInfo::StructuredCloneReadInfo()
|
||||
: mDatabase(nullptr)
|
||||
StructuredCloneReadInfo::StructuredCloneReadInfo(JS::StructuredCloneScope aScope)
|
||||
: mData(aScope)
|
||||
, mDatabase(nullptr)
|
||||
, mHasPreprocessInfo(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
|
||||
}
|
||||
|
||||
inline
|
||||
StructuredCloneReadInfo::StructuredCloneReadInfo()
|
||||
: StructuredCloneReadInfo(JS::StructuredCloneScope::DifferentProcessForIndexedDB)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
StructuredCloneReadInfo::StructuredCloneReadInfo(
|
||||
StructuredCloneReadInfo&& aCloneReadInfo)
|
||||
|
@ -39,6 +39,7 @@ StructuredCloneData::StructuredCloneData(TransferringSupport aSupportsTransferri
|
||||
: StructuredCloneHolder(StructuredCloneHolder::CloningSupported,
|
||||
aSupportsTransferring,
|
||||
StructuredCloneHolder::StructuredCloneScope::DifferentProcess)
|
||||
, mExternalData(JS::StructuredCloneScope::DifferentProcess)
|
||||
, mInitialized(false)
|
||||
{}
|
||||
|
||||
@ -124,7 +125,7 @@ StructuredCloneData::Write(JSContext* aCx,
|
||||
return;
|
||||
}
|
||||
|
||||
JSStructuredCloneData data;
|
||||
JSStructuredCloneData data(mBuffer->scope());
|
||||
mBuffer->abandon();
|
||||
mBuffer->steal(&data);
|
||||
mBuffer = nullptr;
|
||||
@ -151,7 +152,7 @@ BuildClonedMessageData(M* aManager, StructuredCloneData& aData,
|
||||
auto iter = aData.Data().Start();
|
||||
size_t size = aData.Data().Size();
|
||||
bool success;
|
||||
buffer.data = aData.Data().Borrow<js::SystemAllocPolicy>(iter, size, &success);
|
||||
buffer.data = aData.Data().Borrow(iter, size, &success);
|
||||
if (NS_WARN_IF(!success)) {
|
||||
return false;
|
||||
}
|
||||
@ -422,7 +423,7 @@ StructuredCloneData::ReadIPCParams(const IPC::Message* aMsg,
|
||||
PickleIterator* aIter)
|
||||
{
|
||||
MOZ_ASSERT(!mInitialized);
|
||||
JSStructuredCloneData data;
|
||||
JSStructuredCloneData data(JS::StructuredCloneScope::DifferentProcess);
|
||||
if (!ReadParam(aMsg, aIter, &data)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
static already_AddRefed<SharedJSAllocatedData>
|
||||
CreateFromExternalData(const char* aData, size_t aDataLength)
|
||||
{
|
||||
JSStructuredCloneData buf;
|
||||
JSStructuredCloneData buf(JS::StructuredCloneScope::DifferentProcess);
|
||||
buf.AppendBytes(aData, aDataLength);
|
||||
RefPtr<SharedJSAllocatedData> sharedData =
|
||||
new SharedJSAllocatedData(Move(buf));
|
||||
@ -64,7 +64,7 @@ public:
|
||||
static already_AddRefed<SharedJSAllocatedData>
|
||||
CreateFromExternalData(const JSStructuredCloneData& aData)
|
||||
{
|
||||
JSStructuredCloneData buf;
|
||||
JSStructuredCloneData buf(aData.scope());
|
||||
buf.Append(aData);
|
||||
RefPtr<SharedJSAllocatedData> sharedData =
|
||||
new SharedJSAllocatedData(Move(buf));
|
||||
@ -236,8 +236,7 @@ public:
|
||||
{
|
||||
auto iter = aData.Start();
|
||||
bool success = false;
|
||||
mExternalData =
|
||||
aData.Borrow<js::SystemAllocPolicy>(iter, aData.Size(), &success);
|
||||
mExternalData = aData.Borrow(iter, aData.Size(), &success);
|
||||
mInitialized = true;
|
||||
return success;
|
||||
}
|
||||
@ -266,6 +265,11 @@ public:
|
||||
return mSharedData ? mSharedData->Data() : mExternalData;
|
||||
}
|
||||
|
||||
void InitScope(JS::StructuredCloneScope aScope)
|
||||
{
|
||||
Data().initScope(aScope);
|
||||
}
|
||||
|
||||
size_t DataLength() const
|
||||
{
|
||||
return mSharedData ? mSharedData->DataLength() : mExternalData.Size();
|
||||
|
@ -419,9 +419,9 @@ nsPluginTag::InitSandboxLevel()
|
||||
}
|
||||
|
||||
#if defined(_AMD64_)
|
||||
// As level 2 is now the default NPAPI sandbox level for 64-bit flash, we
|
||||
// don't want to allow a lower setting. This should be changed if the
|
||||
// firefox.js pref file is changed.
|
||||
// Level 3 is now the default NPAPI sandbox level for 64-bit flash.
|
||||
// We permit the user to drop the sandbox level by at most 1. This should
|
||||
// be kept up to date with the default value in the firefox.js pref file.
|
||||
if (mIsFlashPlugin && mSandboxLevel < 2) {
|
||||
mSandboxLevel = 2;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#if defined(XP_WIN)
|
||||
#include <commdlg.h>
|
||||
#include <schannel.h>
|
||||
#include <sddl.h>
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
using namespace mozilla;
|
||||
@ -30,10 +31,199 @@ void FreeDestructor(void* aObj) { free(aObj); }
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
// Specialization of EndpointHandlers for Flash file dialog brokering.
|
||||
struct FileDlgEHContainer
|
||||
{
|
||||
template<Endpoint e> struct EndpointHandler;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct FileDlgEHContainer::EndpointHandler<CLIENT> :
|
||||
public BaseEndpointHandler<CLIENT, FileDlgEHContainer::EndpointHandler<CLIENT>>
|
||||
{
|
||||
using BaseEndpointHandler<CLIENT, EndpointHandler<CLIENT>>::Copy;
|
||||
|
||||
inline static void Copy(OpenFileNameIPC& aDest, const LPOPENFILENAMEW& aSrc)
|
||||
{
|
||||
aDest.CopyFromOfn(aSrc);
|
||||
}
|
||||
inline static void Copy(LPOPENFILENAMEW& aDest, const OpenFileNameRetIPC& aSrc)
|
||||
{
|
||||
aSrc.AddToOfn(aDest);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct FileDlgEHContainer::EndpointHandler<SERVER> :
|
||||
public BaseEndpointHandler<SERVER, FileDlgEHContainer::EndpointHandler<SERVER>>
|
||||
{
|
||||
using BaseEndpointHandler<SERVER, EndpointHandler<SERVER>>::Copy;
|
||||
|
||||
inline static void Copy(OpenFileNameRetIPC& aDest, const LPOPENFILENAMEW& aSrc)
|
||||
{
|
||||
aDest.CopyFromOfn(aSrc);
|
||||
}
|
||||
inline static void Copy(ServerCallData* aScd, LPOPENFILENAMEW& aDest, const OpenFileNameIPC& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
ServerCallData::DestructorType* destructor =
|
||||
[](void* aObj) {
|
||||
OpenFileNameIPC::FreeOfnStrings(static_cast<LPOPENFILENAMEW>(aObj));
|
||||
DeleteDestructor<OPENFILENAMEW>(aObj);
|
||||
};
|
||||
aDest = aScd->Allocate<OPENFILENAMEW>(destructor);
|
||||
aSrc.AllocateOfnStrings(aDest);
|
||||
aSrc.AddToOfn(aDest);
|
||||
}
|
||||
};
|
||||
|
||||
// FunctionBroker type that uses FileDlgEHContainer
|
||||
template <FunctionHookId functionId, typename FunctionType>
|
||||
using FileDlgFunctionBroker = FunctionBroker<functionId, FunctionType, FileDlgEHContainer>;
|
||||
|
||||
// Specialization of EndpointHandlers for Flash SSL brokering.
|
||||
struct SslEHContainer {
|
||||
template<Endpoint e> struct EndpointHandler;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SslEHContainer::EndpointHandler<CLIENT> :
|
||||
public BaseEndpointHandler<CLIENT, SslEHContainer::EndpointHandler<CLIENT>>
|
||||
{
|
||||
using BaseEndpointHandler<CLIENT, EndpointHandler<CLIENT>>::Copy;
|
||||
|
||||
inline static void Copy(uint64_t& aDest, const PSecHandle& aSrc)
|
||||
{
|
||||
MOZ_ASSERT((aSrc->dwLower == aSrc->dwUpper) && IsOdd(aSrc->dwLower));
|
||||
aDest = static_cast<uint64_t>(aSrc->dwLower);
|
||||
}
|
||||
inline static void Copy(PSecHandle& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(IsOdd(aSrc));
|
||||
aDest->dwLower = static_cast<ULONG_PTR>(aSrc);
|
||||
aDest->dwUpper = static_cast<ULONG_PTR>(aSrc);
|
||||
}
|
||||
inline static void Copy(IPCSchannelCred& aDest, const PSCHANNEL_CRED& aSrc)
|
||||
{
|
||||
if (aSrc) {
|
||||
aDest.CopyFrom(aSrc);
|
||||
}
|
||||
}
|
||||
inline static void Copy(IPCInternetBuffers& aDest, const LPINTERNET_BUFFERSA& aSrc)
|
||||
{
|
||||
aDest.CopyFrom(aSrc);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SslEHContainer::EndpointHandler<SERVER> :
|
||||
public BaseEndpointHandler<SERVER, SslEHContainer::EndpointHandler<SERVER>>
|
||||
{
|
||||
using BaseEndpointHandler<SERVER, EndpointHandler<SERVER>>::Copy;
|
||||
|
||||
// PSecHandle is the same thing as PCtxtHandle and PCredHandle.
|
||||
inline static void Copy(uint64_t& aDest, const PSecHandle& aSrc)
|
||||
{
|
||||
// If the SecHandle was an error then don't store it.
|
||||
if (!aSrc) {
|
||||
aDest = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static uint64_t sNextVal = 1;
|
||||
UlongPair key(aSrc->dwLower, aSrc->dwUpper);
|
||||
// Fetch val by reference to update the value in the map
|
||||
uint64_t& val = sPairToIdMap[key];
|
||||
if (val == 0) {
|
||||
MOZ_ASSERT(IsOdd(sNextVal));
|
||||
val = sNextVal;
|
||||
sIdToPairMap[val] = key;
|
||||
sNextVal += 2;
|
||||
}
|
||||
aDest = val;
|
||||
}
|
||||
|
||||
// HANDLEs and HINTERNETs marshal with obfuscation (for return values)
|
||||
inline static void Copy(uint64_t& aDest, void* const & aSrc)
|
||||
{
|
||||
// If the HANDLE/HINTERNET was an error then don't store it.
|
||||
if (!aSrc) {
|
||||
aDest = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static uint64_t sNextVal = 1;
|
||||
// Fetch val by reference to update the value in the map
|
||||
uint64_t& val = sPtrToIdMap[aSrc];
|
||||
if (val == 0) {
|
||||
MOZ_ASSERT(IsOdd(sNextVal));
|
||||
val = sNextVal;
|
||||
sIdToPtrMap[val] = aSrc;
|
||||
sNextVal += 2;
|
||||
}
|
||||
aDest = val;
|
||||
}
|
||||
|
||||
// HANDLEs and HINTERNETs unmarshal with obfuscation
|
||||
inline static void Copy(void*& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
aDest = nullptr;
|
||||
MOZ_RELEASE_ASSERT(IsOdd(aSrc));
|
||||
|
||||
// If the src is not found in the map then we get aDest == 0
|
||||
void* ptr = sIdToPtrMap[aSrc];
|
||||
aDest = reinterpret_cast<void*>(ptr);
|
||||
MOZ_RELEASE_ASSERT(aDest);
|
||||
}
|
||||
|
||||
inline static void Copy(PSCHANNEL_CRED& aDest, const IPCSchannelCred& aSrc)
|
||||
{
|
||||
if (aDest) {
|
||||
aSrc.CopyTo(aDest);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Copy(ServerCallData* aScd, PSecHandle& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
MOZ_RELEASE_ASSERT(IsOdd(aSrc));
|
||||
|
||||
// If the src is not found in the map then we get the pair { 0, 0 }
|
||||
aDest = aScd->Allocate<SecHandle>();
|
||||
const UlongPair& pair = sIdToPairMap[aSrc];
|
||||
MOZ_RELEASE_ASSERT(pair.first || pair.second);
|
||||
aDest->dwLower = pair.first;
|
||||
aDest->dwUpper = pair.second;
|
||||
}
|
||||
|
||||
inline static void Copy(ServerCallData* aScd, PSCHANNEL_CRED& aDest, const IPCSchannelCred& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
aDest = aScd->Allocate<SCHANNEL_CRED>();
|
||||
Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
inline static void Copy(ServerCallData* aScd, LPINTERNET_BUFFERSA& aDest, const IPCInternetBuffers& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
aSrc.CopyTo(aDest);
|
||||
ServerCallData::DestructorType* destructor =
|
||||
[](void* aObj) {
|
||||
LPINTERNET_BUFFERSA inetBuf = static_cast<LPINTERNET_BUFFERSA>(aObj);
|
||||
IPCInternetBuffers::FreeBuffers(inetBuf);
|
||||
FreeDestructor(inetBuf);
|
||||
};
|
||||
aScd->PostDestructor(aDest, destructor);
|
||||
}
|
||||
};
|
||||
|
||||
// FunctionBroker type that uses SslEHContainer
|
||||
template <FunctionHookId functionId, typename FunctionType>
|
||||
using SslFunctionBroker = FunctionBroker<functionId, FunctionType, SslEHContainer>;
|
||||
|
||||
/* GetKeyState */
|
||||
|
||||
typedef FunctionBroker<ID_GetKeyState,
|
||||
decltype(GetKeyState)> GetKeyStateFB;
|
||||
typedef FunctionBroker<ID_GetKeyState, decltype(GetKeyState)> GetKeyStateFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -46,8 +236,8 @@ typedef FunctionBroker<ID_SetCursorPos,
|
||||
|
||||
/* GetSaveFileNameW */
|
||||
|
||||
typedef FunctionBroker<ID_GetSaveFileNameW,
|
||||
decltype(GetSaveFileNameW)> GetSaveFileNameWFB;
|
||||
typedef FileDlgFunctionBroker<ID_GetSaveFileNameW,
|
||||
decltype(GetSaveFileNameW)> GetSaveFileNameWFB;
|
||||
|
||||
// Remember files granted access in the chrome process
|
||||
static void GrantFileAccess(base::ProcessId aClientId, LPOPENFILENAME& aLpofn,
|
||||
@ -110,8 +300,8 @@ struct GetSaveFileNameWFB::Response::Info::ShouldMarshal<0> { static const bool
|
||||
|
||||
/* GetOpenFileNameW */
|
||||
|
||||
typedef FunctionBroker<ID_GetOpenFileNameW,
|
||||
decltype(GetOpenFileNameW)> GetOpenFileNameWFB;
|
||||
typedef FileDlgFunctionBroker<ID_GetOpenFileNameW,
|
||||
decltype(GetOpenFileNameW)> GetOpenFileNameWFB;
|
||||
|
||||
template<> template<>
|
||||
BOOL GetOpenFileNameWFB::RunFunction(GetOpenFileNameWFB::FunctionType* aOrigFunction,
|
||||
@ -131,8 +321,8 @@ struct GetOpenFileNameWFB::Response::Info::ShouldMarshal<0> { static const bool
|
||||
|
||||
/* InternetOpenA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetOpenA,
|
||||
decltype(InternetOpenA)> InternetOpenAFB;
|
||||
typedef SslFunctionBroker<ID_InternetOpenA,
|
||||
decltype(InternetOpenA)> InternetOpenAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -140,8 +330,8 @@ InternetOpenAFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
/* InternetConnectA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetConnectA,
|
||||
decltype(InternetConnectA)> InternetConnectAFB;
|
||||
typedef SslFunctionBroker<ID_InternetConnectA,
|
||||
decltype(InternetConnectA)> InternetConnectAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -161,8 +351,8 @@ bool ICAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
|
||||
/* InternetCloseHandle */
|
||||
|
||||
typedef FunctionBroker<ID_InternetCloseHandle,
|
||||
decltype(InternetCloseHandle)> InternetCloseHandleFB;
|
||||
typedef SslFunctionBroker<ID_InternetCloseHandle,
|
||||
decltype(InternetCloseHandle)> InternetCloseHandleFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -181,17 +371,15 @@ bool ICHReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h)
|
||||
|
||||
/* InternetQueryDataAvailable */
|
||||
|
||||
typedef FunctionBroker<ID_InternetQueryDataAvailable,
|
||||
decltype(InternetQueryDataAvailable)> InternetQueryDataAvailableFB;
|
||||
typedef SslFunctionBroker<ID_InternetQueryDataAvailable,
|
||||
decltype(InternetQueryDataAvailable)> InternetQueryDataAvailableFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
InternetQueryDataAvailableFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef InternetQueryDataAvailableFB::Request IQDAReq;
|
||||
|
||||
typedef struct RequestHandler<ID_InternetQueryDataAvailable,
|
||||
BOOL HOOK_CALL (HINTERNET)> IQDADelegateReq;
|
||||
typedef InternetQueryDataAvailableFB::RequestDelegate<BOOL HOOK_CALL (HINTERNET)> IQDADelegateReq;
|
||||
|
||||
template<>
|
||||
void IQDAReq::Marshal(IpdlTuple& aTuple, const HINTERNET& file,
|
||||
@ -233,16 +421,15 @@ struct InternetQueryDataAvailableFB::Response::Info::ShouldMarshal<1> { static c
|
||||
|
||||
/* InternetReadFile */
|
||||
|
||||
typedef FunctionBroker<ID_InternetReadFile,
|
||||
decltype(InternetReadFile)> InternetReadFileFB;
|
||||
typedef SslFunctionBroker<ID_InternetReadFile,
|
||||
decltype(InternetReadFile)> InternetReadFileFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
InternetReadFileFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef InternetReadFileFB::Request IRFRequestHandler;
|
||||
typedef struct RequestHandler<ID_InternetReadFile,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD)> IRFDelegateReq;
|
||||
typedef InternetReadFileFB::RequestDelegate<BOOL HOOK_CALL (HINTERNET, DWORD)> IRFDelegateReq;
|
||||
|
||||
template<>
|
||||
void IRFRequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
@ -280,13 +467,12 @@ bool IRFRequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
typedef InternetReadFileFB::Response IRFResponseHandler;
|
||||
typedef InternetReadFileFB::ResponseDelegate<BOOL HOOK_CALL (nsDependentCSubstring)> IRFDelegateResponseHandler;
|
||||
|
||||
// Marshal the output parameter that we sent to the response delegate.
|
||||
template<> template<>
|
||||
struct InternetReadFileFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
|
||||
|
||||
typedef ResponseHandler<ID_InternetReadFile, decltype(InternetReadFile)> IRFResponseHandler;
|
||||
typedef ResponseHandler<ID_InternetReadFile,
|
||||
BOOL HOOK_CALL (nsDependentCSubstring)> IRFDelegateResponseHandler;
|
||||
struct IRFResponseHandler::Info::ShouldMarshal<0> { static const bool value = true; };
|
||||
|
||||
template<>
|
||||
void IRFResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
|
||||
@ -321,16 +507,15 @@ bool IRFResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNET
|
||||
|
||||
/* InternetWriteFile */
|
||||
|
||||
typedef FunctionBroker<ID_InternetWriteFile,
|
||||
decltype(InternetWriteFile)> InternetWriteFileFB;
|
||||
typedef SslFunctionBroker<ID_InternetWriteFile,
|
||||
decltype(InternetWriteFile)> InternetWriteFileFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
InternetWriteFileFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef InternetWriteFileFB::Request IWFReqHandler;
|
||||
typedef RequestHandler<ID_InternetWriteFile,
|
||||
int HOOK_CALL (HINTERNET, nsDependentCSubstring)> IWFDelegateReqHandler;
|
||||
typedef InternetWriteFileFB::RequestDelegate<int HOOK_CALL (HINTERNET, nsDependentCSubstring)> IWFDelegateReqHandler;
|
||||
|
||||
template<>
|
||||
void IWFReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& file, const LPCVOID& buf,
|
||||
@ -372,16 +557,15 @@ struct InternetWriteFileFB::Response::Info::ShouldMarshal<3> { static const bool
|
||||
|
||||
/* InternetSetOptionA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetSetOptionA,
|
||||
decltype(InternetSetOptionA)> InternetSetOptionAFB;
|
||||
typedef SslFunctionBroker<ID_InternetSetOptionA,
|
||||
decltype(InternetSetOptionA)> InternetSetOptionAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
InternetSetOptionAFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef InternetSetOptionAFB::Request ISOAReqHandler;
|
||||
typedef RequestHandler<ID_InternetSetOptionA,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD, nsDependentCSubstring)> ISOADelegateReqHandler;
|
||||
typedef InternetSetOptionAFB::RequestDelegate<BOOL HOOK_CALL (HINTERNET, DWORD, nsDependentCSubstring)> ISOADelegateReqHandler;
|
||||
|
||||
template<>
|
||||
void ISOAReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h, const DWORD& opt,
|
||||
@ -417,8 +601,8 @@ bool ISOAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h, const D
|
||||
|
||||
/* HttpAddRequestHeadersA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpAddRequestHeadersA,
|
||||
decltype(HttpAddRequestHeadersA)> HttpAddRequestHeadersAFB;
|
||||
typedef SslFunctionBroker<ID_HttpAddRequestHeadersA,
|
||||
decltype(HttpAddRequestHeadersA)> HttpAddRequestHeadersAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -439,17 +623,15 @@ bool HARHAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
|
||||
/* HttpOpenRequestA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpOpenRequestA,
|
||||
decltype(HttpOpenRequestA)> HttpOpenRequestAFB;
|
||||
typedef SslFunctionBroker<ID_HttpOpenRequestA,
|
||||
decltype(HttpOpenRequestA)> HttpOpenRequestAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
HttpOpenRequestAFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef HttpOpenRequestAFB::Request HORAReqHandler;
|
||||
typedef RequestHandler<ID_HttpOpenRequestA,
|
||||
HINTERNET HOOK_CALL (HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR,
|
||||
nsTArray<nsCString>, DWORD, DWORD_PTR)> HORADelegateReqHandler;
|
||||
typedef HttpOpenRequestAFB::RequestDelegate<HINTERNET HOOK_CALL (HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR, nsTArray<nsCString>, DWORD, DWORD_PTR)> HORADelegateReqHandler;
|
||||
|
||||
template<>
|
||||
void HORAReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
@ -507,17 +689,15 @@ bool HORAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
|
||||
/* HttpQueryInfoA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpQueryInfoA,
|
||||
decltype(HttpQueryInfoA)> HttpQueryInfoAFB;
|
||||
typedef SslFunctionBroker<ID_HttpQueryInfoA,
|
||||
decltype(HttpQueryInfoA)> HttpQueryInfoAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
HttpQueryInfoAFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef HttpQueryInfoAFB::Request HQIARequestHandler;
|
||||
typedef RequestHandler<ID_HttpQueryInfoA,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD, BOOL, DWORD, BOOL,
|
||||
DWORD)> HQIADelegateRequestHandler;
|
||||
typedef HttpQueryInfoAFB::RequestDelegate<BOOL HOOK_CALL (HINTERNET, DWORD, BOOL, DWORD, BOOL, DWORD)> HQIADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void HQIARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
@ -572,9 +752,7 @@ template<> template<>
|
||||
struct HttpQueryInfoAFB::Response::Info::ShouldMarshal<2> { static const bool value = true; };
|
||||
|
||||
typedef HttpQueryInfoAFB::Response HQIAResponseHandler;
|
||||
typedef ResponseHandler<ID_HttpQueryInfoA,
|
||||
BOOL HOOK_CALL (nsDependentCSubstring,
|
||||
DWORD, DWORD)> HQIADelegateResponseHandler;
|
||||
typedef HttpQueryInfoAFB::ResponseDelegate<BOOL HOOK_CALL (nsDependentCSubstring, DWORD, DWORD)> HQIADelegateResponseHandler;
|
||||
|
||||
template<>
|
||||
void HQIAResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
|
||||
@ -631,17 +809,15 @@ bool HQIAResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNE
|
||||
|
||||
/* HttpSendRequestA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpSendRequestA,
|
||||
decltype(HttpSendRequestA)> HttpSendRequestAFB;
|
||||
typedef SslFunctionBroker<ID_HttpSendRequestA,
|
||||
decltype(HttpSendRequestA)> HttpSendRequestAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
HttpSendRequestAFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef HttpSendRequestAFB::Request HSRARequestHandler;
|
||||
typedef RequestHandler<ID_HttpSendRequestA,
|
||||
BOOL HOOK_CALL (HINTERNET, nsDependentCSubstring,
|
||||
nsDependentCSubstring)> HSRADelegateRequestHandler;
|
||||
typedef HttpSendRequestAFB::RequestDelegate<BOOL HOOK_CALL (HINTERNET, nsDependentCSubstring, nsDependentCSubstring)> HSRADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void HSRARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
@ -709,8 +885,8 @@ bool HSRARequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
|
||||
/* HttpSendRequestExA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpSendRequestExA,
|
||||
decltype(HttpSendRequestExA)> HttpSendRequestExAFB;
|
||||
typedef SslFunctionBroker<ID_HttpSendRequestExA,
|
||||
decltype(HttpSendRequestExA)> HttpSendRequestExAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -733,16 +909,15 @@ const DWORD_PTR HSRExAReqInfo::FixedValue<4>::value = 0;
|
||||
|
||||
/* InternetQueryOptionA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetQueryOptionA,
|
||||
decltype(InternetQueryOptionA)> InternetQueryOptionAFB;
|
||||
typedef SslFunctionBroker<ID_InternetQueryOptionA,
|
||||
decltype(InternetQueryOptionA)> InternetQueryOptionAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
InternetQueryOptionAFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_SSL>;
|
||||
|
||||
typedef InternetQueryOptionAFB::Request IQOARequestHandler;
|
||||
typedef RequestHandler<ID_InternetQueryOptionA,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD, DWORD)> IQOADelegateRequestHandler;
|
||||
typedef InternetQueryOptionAFB::RequestDelegate<BOOL HOOK_CALL (HINTERNET, DWORD, DWORD)> IQOADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void IQOARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
@ -785,8 +960,7 @@ template<> template<>
|
||||
struct InternetQueryOptionAFB::Response::Info::ShouldMarshal<1> { static const bool value = true; };
|
||||
|
||||
typedef InternetQueryOptionAFB::Response IQOAResponseHandler;
|
||||
typedef ResponseHandler<ID_InternetQueryOptionA,
|
||||
BOOL HOOK_CALL (nsDependentCSubstring, DWORD)> IQOADelegateResponseHandler;
|
||||
typedef InternetQueryOptionAFB::ResponseDelegate<BOOL HOOK_CALL (nsDependentCSubstring, DWORD)> IQOADelegateResponseHandler;
|
||||
|
||||
template<>
|
||||
void IQOAResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
|
||||
@ -820,8 +994,8 @@ bool IQOAResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNE
|
||||
|
||||
/* InternetErrorDlg */
|
||||
|
||||
typedef FunctionBroker<ID_InternetErrorDlg,
|
||||
decltype(InternetErrorDlg)> InternetErrorDlgFB;
|
||||
typedef SslFunctionBroker<ID_InternetErrorDlg,
|
||||
decltype(InternetErrorDlg)> InternetErrorDlgFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -853,8 +1027,8 @@ bool IEDReqHandler::ShouldBroker(Endpoint endpoint, const HWND& hwnd,
|
||||
|
||||
/* AcquireCredentialsHandleA */
|
||||
|
||||
typedef FunctionBroker<ID_AcquireCredentialsHandleA,
|
||||
decltype(AcquireCredentialsHandleA)> AcquireCredentialsHandleAFB;
|
||||
typedef SslFunctionBroker<ID_AcquireCredentialsHandleA,
|
||||
decltype(AcquireCredentialsHandleA)> AcquireCredentialsHandleAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -887,10 +1061,7 @@ struct ACHAReqInfo::FixedValue<6> { static void* const value; };
|
||||
void* const ACHAReqInfo::FixedValue<6>::value = nullptr;
|
||||
|
||||
typedef AcquireCredentialsHandleAFB::Request ACHARequestHandler;
|
||||
typedef RequestHandler<ID_AcquireCredentialsHandleA,
|
||||
SECURITY_STATUS HOOK_CALL (LPSTR, LPSTR, unsigned long,
|
||||
void*, PSCHANNEL_CRED, SEC_GET_KEY_FN,
|
||||
void*)> ACHADelegateRequestHandler;
|
||||
typedef AcquireCredentialsHandleAFB::RequestDelegate<SECURITY_STATUS HOOK_CALL (LPSTR, LPSTR, unsigned long, void*, PSCHANNEL_CRED, SEC_GET_KEY_FN, void*)> ACHADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void ACHARequestHandler::Marshal(IpdlTuple& aTuple, const LPSTR& principal,
|
||||
@ -932,8 +1103,8 @@ struct ACHARspInfo::ShouldMarshal<8> { static const bool value = true; };
|
||||
|
||||
/* QueryCredentialsAttributesA */
|
||||
|
||||
typedef FunctionBroker<ID_QueryCredentialsAttributesA,
|
||||
decltype(QueryCredentialsAttributesA)> QueryCredentialsAttributesAFB;
|
||||
typedef SslFunctionBroker<ID_QueryCredentialsAttributesA,
|
||||
decltype(QueryCredentialsAttributesA)> QueryCredentialsAttributesAFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -941,8 +1112,8 @@ QueryCredentialsAttributesAFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_
|
||||
|
||||
/* FreeCredentialsHandle */
|
||||
|
||||
typedef FunctionBroker<ID_FreeCredentialsHandle,
|
||||
decltype(FreeCredentialsHandle)> FreeCredentialsHandleFB;
|
||||
typedef SslFunctionBroker<ID_FreeCredentialsHandle,
|
||||
decltype(FreeCredentialsHandle)> FreeCredentialsHandleFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
@ -960,6 +1131,128 @@ bool FCHReq::ShouldBroker(Endpoint endpoint, const PCredHandle& h)
|
||||
((h->dwLower == h->dwUpper) && IsOdd(static_cast<uint64_t>(h->dwLower)));
|
||||
}
|
||||
|
||||
/* CreateMutexW */
|
||||
|
||||
// Get the user's SID as a string. Returns an empty string on failure.
|
||||
static std::wstring GetUserSid()
|
||||
{
|
||||
std::wstring ret;
|
||||
// Get user SID from process token information
|
||||
HANDLE token;
|
||||
BOOL success = ::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token);
|
||||
if (!success) {
|
||||
return ret;
|
||||
}
|
||||
DWORD bufLen;
|
||||
success = ::GetTokenInformation(token, TokenUser, nullptr, 0, &bufLen);
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||
return ret;
|
||||
}
|
||||
void* buf = malloc(bufLen);
|
||||
success = ::GetTokenInformation(token, TokenUser, buf, bufLen, &bufLen);
|
||||
MOZ_ASSERT(success);
|
||||
if (success) {
|
||||
TOKEN_USER* tokenUser = static_cast<TOKEN_USER*>(buf);
|
||||
PSID sid = tokenUser->User.Sid;
|
||||
LPWSTR sidStr;
|
||||
success = ::ConvertSidToStringSid(sid, &sidStr);
|
||||
if (success) {
|
||||
ret = sidStr;
|
||||
::LocalFree(sidStr);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
::CloseHandle(token);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the name Windows uses for the camera mutex. Returns an empty string
|
||||
// on failure.
|
||||
// The camera mutex is identified in Windows code using a hard-coded GUID string,
|
||||
// "eed3bd3a-a1ad-4e99-987b-d7cb3fcfa7f0", and the user's SID. The GUID
|
||||
// value was determined by investigating Windows code. It is referenced in
|
||||
// CCreateSwEnum::CCreateSwEnum(void) in devenum.dll.
|
||||
static std::wstring GetCameraMutexName()
|
||||
{
|
||||
std::wstring userSid = GetUserSid();
|
||||
if (userSid.empty()) {
|
||||
return userSid;
|
||||
}
|
||||
return std::wstring(L"eed3bd3a-a1ad-4e99-987b-d7cb3fcfa7f0 - ") + userSid;
|
||||
}
|
||||
|
||||
typedef FunctionBroker<ID_CreateMutexW, decltype(CreateMutexW)> CreateMutexWFB;
|
||||
|
||||
template<>
|
||||
ShouldHookFunc* const
|
||||
CreateMutexWFB::BaseType::mShouldHook = &CheckQuirks<QUIRK_FLASH_HOOK_CREATEMUTEXW>;
|
||||
|
||||
typedef CreateMutexWFB::Request CMWReqHandler;
|
||||
typedef CMWReqHandler::Info CMWReqInfo;
|
||||
typedef CreateMutexWFB::Response CMWRspHandler;
|
||||
|
||||
template<>
|
||||
bool CMWReqHandler::ShouldBroker(Endpoint endpoint,
|
||||
const LPSECURITY_ATTRIBUTES& aAttribs,
|
||||
const BOOL& aOwner,
|
||||
const LPCWSTR& aName)
|
||||
{
|
||||
// Statically hold the camera mutex name so that we dont recompute it for
|
||||
// every CreateMutexW call in the client process.
|
||||
static std::wstring camMutexName = GetCameraMutexName();
|
||||
|
||||
// Only broker if we are requesting the camera mutex. Note that we only
|
||||
// need to check that the client is actually requesting the camera. The
|
||||
// command is always valid on the server as long as we can construct the
|
||||
// mutex name.
|
||||
if (endpoint == SERVER) {
|
||||
return !camMutexName.empty();
|
||||
}
|
||||
|
||||
return (!aOwner) && aName && (!camMutexName.empty()) && (camMutexName == aName);
|
||||
}
|
||||
|
||||
// We dont need to marshal any parameters. We construct all of them server-side.
|
||||
template<> template<>
|
||||
struct CMWReqInfo::ShouldMarshal<0> { static const bool value = false; };
|
||||
template<> template<>
|
||||
struct CMWReqInfo::ShouldMarshal<1> { static const bool value = false; };
|
||||
template<> template<>
|
||||
struct CMWReqInfo::ShouldMarshal<2> { static const bool value = false; };
|
||||
|
||||
template<> template<>
|
||||
HANDLE CreateMutexWFB::RunFunction(CreateMutexWFB::FunctionType* aOrigFunction,
|
||||
base::ProcessId aClientId,
|
||||
LPSECURITY_ATTRIBUTES& aAttribs,
|
||||
BOOL& aOwner,
|
||||
LPCWSTR& aName) const
|
||||
{
|
||||
// Use CreateMutexW to get the camera mutex and DuplicateHandle to open it
|
||||
// for use in the child process.
|
||||
// Recall that aAttribs, aOwner and aName are all unmarshaled so they are
|
||||
// unassigned garbage.
|
||||
SECURITY_ATTRIBUTES mutexAttrib =
|
||||
{ sizeof(SECURITY_ATTRIBUTES), nullptr /* ignored */, TRUE };
|
||||
std::wstring camMutexName = GetCameraMutexName();
|
||||
if (camMutexName.empty()) {
|
||||
return 0;
|
||||
}
|
||||
HANDLE serverMutex = ::CreateMutexW(&mutexAttrib, FALSE, camMutexName.c_str());
|
||||
if (serverMutex == 0) {
|
||||
return 0;
|
||||
}
|
||||
ScopedProcessHandle clientProcHandle;
|
||||
if (!base::OpenProcessHandle(aClientId, &clientProcHandle.rwget())) {
|
||||
return 0;
|
||||
}
|
||||
HANDLE ret;
|
||||
if (!::DuplicateHandle(::GetCurrentProcess(), serverMutex, clientProcHandle,
|
||||
&ret, SYNCHRONIZE, FALSE, DUPLICATE_CLOSE_SOURCE)) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -1035,6 +1328,8 @@ AddBrokeredFunctionHooks(FunctionHookArray& aHooks)
|
||||
FUN_HOOK(new FreeCredentialsHandleFB("sspicli.dll",
|
||||
"FreeCredentialsHandle",
|
||||
&FreeCredentialsHandle));
|
||||
aHooks[ID_CreateMutexW] =
|
||||
FUN_HOOK(new CreateMutexWFB("kernel32.dll", "CreateMutexW", &CreateMutexW));
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,10 @@
|
||||
* for client -> server and for server -> client. Note that the
|
||||
* types must be able to Copy() from one another -- the default Copy()
|
||||
* implementation uses the type's assignment operator.
|
||||
* See e.g. EndpointHandler<CLIENT>::IPCTypeMap<LPOPENFILENAMEW>.
|
||||
* The EndpointHandler itself is a template parameter of the FunctionBroker.
|
||||
* The default EndpointHandler recognizes basic types.
|
||||
* See e.g. FileDlgEndpointHandler<CLIENT>::IPCTypeMap<LPOPENFILENAMEW>
|
||||
* for an example of specialization.
|
||||
*
|
||||
* * Anything more complex involving parameter transmission:
|
||||
*
|
||||
@ -456,15 +459,16 @@ inline void Copy(PTimeStamp& aDest, const uint64_t& aSrc)
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
template<Endpoint e> struct EndpointHandler;
|
||||
template<> struct EndpointHandler<CLIENT> {
|
||||
template<Endpoint e, typename SelfType> struct BaseEndpointHandler;
|
||||
template<typename SelfType>
|
||||
struct BaseEndpointHandler<CLIENT,SelfType> {
|
||||
static const Endpoint OtherSide = SERVER;
|
||||
|
||||
template<typename DestType, typename SrcType>
|
||||
inline static void Copy(ServerCallData* aScd, DestType& aDest, const SrcType& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aScd); // never used in the CLIENT
|
||||
Copy(aDest, aSrc);
|
||||
SelfType::Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
template<typename DestType, typename SrcType>
|
||||
@ -472,109 +476,54 @@ template<> struct EndpointHandler<CLIENT> {
|
||||
{
|
||||
mozilla::plugins::Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
// const char* should be null terminated but this is not always the case.
|
||||
// In those cases, we must override this default behavior.
|
||||
inline static void Copy(nsDependentCSubstring& aDest, const char* const& aSrc)
|
||||
{
|
||||
// In the client, we just bind to the caller's string
|
||||
if (aSrc) {
|
||||
aDest.Rebind(aSrc, strlen(aSrc));
|
||||
} else {
|
||||
aDest.SetIsVoid(true);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Copy(const char*& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Cannot return const parameters.");
|
||||
}
|
||||
|
||||
inline static void Copy(nsDependentCSubstring& aDest, char* const& aSrc)
|
||||
{
|
||||
// In the client, we just bind to the caller's string
|
||||
if (aSrc) {
|
||||
aDest.Rebind(aSrc, strlen(aSrc));
|
||||
} else {
|
||||
aDest.SetIsVoid(true);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Copy(char*& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Returning char* parameters is not yet suported.");
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
inline static void Copy(uint32_t& aDest, const LPDWORD& aSrc)
|
||||
{
|
||||
aDest = *aSrc;
|
||||
}
|
||||
|
||||
inline static void Copy(LPDWORD& aDest, const uint32_t& aSrc)
|
||||
{
|
||||
*aDest = aSrc;
|
||||
}
|
||||
#endif // #if defined(XP_WIN)
|
||||
};
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(uint64_t& aDest, const PSecHandle& aSrc)
|
||||
{
|
||||
MOZ_ASSERT((aSrc->dwLower == aSrc->dwUpper) && IsOdd(aSrc->dwLower));
|
||||
aDest = static_cast<uint64_t>(aSrc->dwLower);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(PSecHandle& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(IsOdd(aSrc));
|
||||
aDest->dwLower = static_cast<ULONG_PTR>(aSrc);
|
||||
aDest->dwUpper = static_cast<ULONG_PTR>(aSrc);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(OpenFileNameIPC& aDest, const LPOPENFILENAMEW& aSrc)
|
||||
{
|
||||
aDest.CopyFromOfn(aSrc);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(LPOPENFILENAMEW& aDest, const OpenFileNameRetIPC& aSrc)
|
||||
{
|
||||
aSrc.AddToOfn(aDest);
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
// const char* should be null terminated but this is not always the case.
|
||||
// In those cases, we must override this default behavior.
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(nsDependentCSubstring& aDest, const char* const& aSrc)
|
||||
{
|
||||
// In the client, we just bind to the caller's string
|
||||
if (aSrc) {
|
||||
aDest.Rebind(aSrc, strlen(aSrc));
|
||||
} else {
|
||||
aDest.SetIsVoid(true);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(const char*& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Cannot return const parameters.");
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(nsDependentCSubstring& aDest, char* const& aSrc)
|
||||
{
|
||||
// In the client, we just bind to the caller's string
|
||||
if (aSrc) {
|
||||
aDest.Rebind(aSrc, strlen(aSrc));
|
||||
} else {
|
||||
aDest.SetIsVoid(true);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(char*& aDest,
|
||||
const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Returning char* parameters is not yet suported.");
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(IPCSchannelCred& aDest,
|
||||
const PSCHANNEL_CRED& aSrc)
|
||||
{
|
||||
if (aSrc) {
|
||||
aDest.CopyFrom(aSrc);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(IPCInternetBuffers& aDest,
|
||||
const LPINTERNET_BUFFERSA& aSrc)
|
||||
{
|
||||
aDest.CopyFrom(aSrc);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(uint32_t& aDest, const LPDWORD& aSrc)
|
||||
{
|
||||
aDest = *aSrc;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<CLIENT>::Copy(LPDWORD& aDest, const uint32_t& aSrc)
|
||||
{
|
||||
*aDest = aSrc;
|
||||
}
|
||||
|
||||
#endif // #if defined(XP_WIN)
|
||||
|
||||
template<> struct EndpointHandler<SERVER> {
|
||||
template<typename SelfType>
|
||||
struct BaseEndpointHandler<SERVER, SelfType> {
|
||||
static const Endpoint OtherSide = CLIENT;
|
||||
|
||||
// Specializations of this method may allocate memory for types that need it
|
||||
@ -585,7 +534,7 @@ template<> struct EndpointHandler<SERVER> {
|
||||
template<typename DestType, typename SrcType>
|
||||
inline static void Copy(ServerCallData* aScd, DestType& aDest, const SrcType& aSrc)
|
||||
{
|
||||
Copy(aDest, aSrc);
|
||||
SelfType::Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
template<typename DestType, typename SrcType>
|
||||
@ -593,196 +542,66 @@ template<> struct EndpointHandler<SERVER> {
|
||||
{
|
||||
mozilla::plugins::Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
inline static void Copy(nsDependentCSubstring& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
aDest.Rebind(aSrc.Data(), aSrc.Length());
|
||||
aDest.SetIsVoid(aSrc.IsVoid());
|
||||
}
|
||||
|
||||
// const char* should be null terminated but this is not always the case.
|
||||
// In those cases, we override this default behavior.
|
||||
inline static void Copy(nsDependentCSubstring& aDest, const char* const& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Const parameter cannot be returned by brokering process.");
|
||||
}
|
||||
|
||||
inline static void Copy(nsDependentCSubstring& aDest, char* const& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Returning char* parameters is not yet suported.");
|
||||
}
|
||||
|
||||
inline static void Copy(ServerCallData* aScd, char*& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
// In the parent, we must allocate the string.
|
||||
MOZ_ASSERT(aScd);
|
||||
if (aSrc.IsVoid()) {
|
||||
aDest = nullptr;
|
||||
return;
|
||||
}
|
||||
aScd->AllocateMemory(aSrc.Length() + 1, aDest);
|
||||
memcpy(aDest, aSrc.Data(), aSrc.Length());
|
||||
aDest[aSrc.Length()] = '\0';
|
||||
}
|
||||
|
||||
inline static void Copy(ServerCallData* aScd, const char*& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
char* nonConstDest;
|
||||
Copy(aScd, nonConstDest, aSrc);
|
||||
aDest = nonConstDest;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
inline static void Copy(uint32_t& aDest, const LPDWORD& aSrc)
|
||||
{
|
||||
aDest = *aSrc;
|
||||
}
|
||||
|
||||
inline static void Copy(LPDWORD& aDest, const uint32_t& aSrc)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aDest);
|
||||
*aDest = aSrc;
|
||||
}
|
||||
|
||||
inline static void Copy(ServerCallData* aScd, PTimeStamp& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
aDest = aScd->Allocate<::TimeStamp>();
|
||||
Copy(aDest, aSrc);
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
};
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(nsDependentCSubstring& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
aDest.Rebind(aSrc.Data(), aSrc.Length());
|
||||
aDest.SetIsVoid(aSrc.IsVoid());
|
||||
}
|
||||
|
||||
// const char* should be null terminated but this is not always the case.
|
||||
// In those cases, we override this default behavior.
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(nsDependentCSubstring& aDest, const char* const& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Const parameter cannot be returned by brokering process.");
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(nsDependentCSubstring& aDest, char* const& aSrc)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Returning char* parameters is not yet suported.");
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
// PSecHandle is the same thing as PCtxtHandle and PCredHandle
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(uint64_t& aDest, const PSecHandle& aSrc)
|
||||
{
|
||||
static uint64_t sNextVal = 1;
|
||||
UlongPair key(aSrc->dwLower, aSrc->dwUpper);
|
||||
// Fetch val by reference to update the value in the map
|
||||
uint64_t& val = sPairToIdMap[key];
|
||||
if (val == 0) {
|
||||
MOZ_ASSERT(IsOdd(sNextVal));
|
||||
val = sNextVal;
|
||||
sIdToPairMap[val] = key;
|
||||
sNextVal += 2;
|
||||
}
|
||||
aDest = val;
|
||||
}
|
||||
|
||||
// HANDLEs and HINTERNETs marshal (for return values)
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(uint64_t& aDest, void* const & aSrc)
|
||||
{
|
||||
// If the HANDLE/HINSTANCE was an error then don't store it.
|
||||
if (!aSrc) {
|
||||
aDest = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static uint64_t sNextVal = 1;
|
||||
// Fetch val by reference to update the value in the map
|
||||
uint64_t& val = sPtrToIdMap[aSrc];
|
||||
if (val == 0) {
|
||||
MOZ_ASSERT(IsOdd(sNextVal));
|
||||
val = sNextVal;
|
||||
sIdToPtrMap[val] = aSrc;
|
||||
sNextVal += 2;
|
||||
}
|
||||
aDest = val;
|
||||
}
|
||||
|
||||
// HANDLEs and HINTERNETs unmarshal
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(void*& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
aDest = nullptr;
|
||||
MOZ_RELEASE_ASSERT(IsOdd(aSrc));
|
||||
|
||||
// If the src is not found in the map then we get aDest == 0
|
||||
void* ptr = sIdToPtrMap[aSrc];
|
||||
aDest = reinterpret_cast<void*>(ptr);
|
||||
MOZ_RELEASE_ASSERT(aDest);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(OpenFileNameRetIPC& aDest, const LPOPENFILENAMEW& aSrc)
|
||||
{
|
||||
aDest.CopyFromOfn(aSrc);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(PSCHANNEL_CRED& aDest, const IPCSchannelCred& aSrc)
|
||||
{
|
||||
if (aDest) {
|
||||
aSrc.CopyTo(aDest);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(uint32_t& aDest, const LPDWORD& aSrc)
|
||||
{
|
||||
aDest = *aSrc;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(LPDWORD& aDest, const uint32_t& aSrc)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aDest);
|
||||
*aDest = aSrc;
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, char*& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
// In the parent, we must allocate the string.
|
||||
MOZ_ASSERT(aScd);
|
||||
if (aSrc.IsVoid()) {
|
||||
aDest = nullptr;
|
||||
return;
|
||||
}
|
||||
aScd->AllocateMemory(aSrc.Length() + 1, aDest);
|
||||
memcpy(aDest, aSrc.Data(), aSrc.Length());
|
||||
aDest[aSrc.Length()] = '\0';
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, const char*& aDest, const nsDependentCSubstring& aSrc)
|
||||
{
|
||||
char* nonConstDest;
|
||||
Copy(aScd, nonConstDest, aSrc);
|
||||
aDest = nonConstDest;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, PSecHandle& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
MOZ_RELEASE_ASSERT(IsOdd(aSrc));
|
||||
|
||||
// If the src is not found in the map then we get the pair { 0, 0 }
|
||||
aDest = aScd->Allocate<SecHandle>();
|
||||
const UlongPair& pair = sIdToPairMap[aSrc];
|
||||
MOZ_RELEASE_ASSERT(pair.first || pair.second);
|
||||
aDest->dwLower = pair.first;
|
||||
aDest->dwUpper = pair.second;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, PTimeStamp& aDest, const uint64_t& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
aDest = aScd->Allocate<::TimeStamp>();
|
||||
Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, LPOPENFILENAMEW& aDest, const OpenFileNameIPC& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
ServerCallData::DestructorType* destructor =
|
||||
[](void* aObj) {
|
||||
OpenFileNameIPC::FreeOfnStrings(static_cast<LPOPENFILENAMEW>(aObj));
|
||||
DeleteDestructor<OPENFILENAMEW>(aObj);
|
||||
};
|
||||
aDest = aScd->Allocate<OPENFILENAMEW>(destructor);
|
||||
aSrc.AllocateOfnStrings(aDest);
|
||||
aSrc.AddToOfn(aDest);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, PSCHANNEL_CRED& aDest, const IPCSchannelCred& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
aDest = aScd->Allocate<SCHANNEL_CRED>();
|
||||
Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, LPINTERNET_BUFFERSA& aDest, const IPCInternetBuffers& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
aSrc.CopyTo(aDest);
|
||||
ServerCallData::DestructorType* destructor =
|
||||
[](void* aObj) {
|
||||
LPINTERNET_BUFFERSA inetBuf = static_cast<LPINTERNET_BUFFERSA>(aObj);
|
||||
IPCInternetBuffers::FreeBuffers(inetBuf);
|
||||
FreeDestructor(inetBuf);
|
||||
};
|
||||
aScd->PostDestructor(aDest, destructor);
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
// PhaseHandler is a RequestHandler or a ResponseHandler.
|
||||
template<Endpoint endpoint, typename PhaseHandler>
|
||||
struct Marshaler
|
||||
@ -818,7 +637,8 @@ struct Marshaler
|
||||
HOOK_LOG(LogLevel::Verbose,
|
||||
("%s marshaling parameter %d.", EndpointMsg(endpoint), paramIndex));
|
||||
IPCType ipcObject;
|
||||
EndpointHandler<endpoint>::Copy(ipcObject, aParam); // Must be able to Copy() from OrigType to IPCType
|
||||
// EndpointHandler must be able to Copy() from OrigType to IPCType
|
||||
PhaseHandler::EHContainer::template EndpointHandler<endpoint>::Copy(ipcObject, aParam);
|
||||
LogParameterValue(paramIndex, ipcObject);
|
||||
aMarshaledTuple.AddElement(ipcObject);
|
||||
}
|
||||
@ -881,7 +701,7 @@ struct Marshaler
|
||||
HOOK_LOG(LogLevel::Verbose,
|
||||
("%s unmarshaled parameter %d.", EndpointMsg(endpoint), tupleIndex));
|
||||
LogParameterValue(tupleIndex, *ipcObject);
|
||||
EndpointHandler<endpoint>::Copy(aUnmarshaledTuple.GetServerCallData(), aParam, *ipcObject);
|
||||
PhaseHandler::EHContainer::template EndpointHandler<endpoint>::Copy(aUnmarshaledTuple.GetServerCallData(), aParam, *ipcObject);
|
||||
++aNextTupleIdx;
|
||||
return true;
|
||||
}
|
||||
@ -923,7 +743,7 @@ struct Marshaler
|
||||
{
|
||||
nsDependentCSubstring tempStr;
|
||||
bool ret = MaybeUnmarshalParameter<tupleIndex, nsDependentCSubstring, true, false>::UnmarshalParameter(aUnmarshaledTuple, aNextTupleIdx, tempStr);
|
||||
EndpointHandler<endpoint>::Copy(aUnmarshaledTuple.GetServerCallData(), aParam, tempStr);
|
||||
PhaseHandler::EHContainer::template EndpointHandler<endpoint>::Copy(aUnmarshaledTuple.GetServerCallData(), aParam, tempStr);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
@ -1022,7 +842,7 @@ template<FunctionHookId functionId> struct RequestInfo
|
||||
* This base stores the RequestHandler's IPCTypeMap. It really only
|
||||
* exists to circumvent the arbitrary C++ rule (enforced by mingw) forbidding
|
||||
* full class specialization of a class (IPCTypeMap<T>) inside of an
|
||||
* unspecialized template class (RequestHandler<T>).p
|
||||
* unspecialized template class (RequestHandler<T>).
|
||||
*/
|
||||
struct RequestHandlerBase
|
||||
{
|
||||
@ -1042,15 +862,20 @@ struct RequestHandlerBase::IPCTypeMap<LPOPENFILENAMEW> { typedef OpenFileNameIPC
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
template<FunctionHookId functionId, typename FunctionType> struct RequestHandler;
|
||||
struct BaseEHContainer {
|
||||
template <Endpoint e> struct EndpointHandler : public BaseEndpointHandler<e,EndpointHandler<e>> {};
|
||||
};
|
||||
|
||||
template<FunctionHookId functionId, typename ResultType, typename ... ParamTypes>
|
||||
struct RequestHandler<functionId, ResultType HOOK_CALL (ParamTypes...)> :
|
||||
template<FunctionHookId functionId, typename FunctionType, typename EHContainer> struct RequestHandler;
|
||||
|
||||
template<FunctionHookId functionId, typename EHContainerType, typename ResultType, typename ... ParamTypes>
|
||||
struct RequestHandler<functionId, ResultType HOOK_CALL (ParamTypes...), EHContainerType> :
|
||||
public RequestHandlerBase
|
||||
{
|
||||
typedef ResultType(HOOK_CALL FunctionType)(ParamTypes...);
|
||||
typedef RequestHandler<functionId, FunctionType> SelfType;
|
||||
typedef RequestHandler<functionId, FunctionType, EHContainerType> SelfType;
|
||||
typedef RequestInfo<functionId> Info;
|
||||
typedef EHContainerType EHContainer;
|
||||
|
||||
static void Marshal(IpdlTuple& aTuple, const ParamTypes&... aParams)
|
||||
{
|
||||
@ -1164,15 +989,16 @@ struct ResponseHandlerBase::IPCTypeMap<LPOPENFILENAMEW> { typedef OpenFileNameRe
|
||||
|
||||
#endif
|
||||
|
||||
template<FunctionHookId functionId, typename FunctionType> struct ResponseHandler;
|
||||
template<FunctionHookId functionId, typename FunctionType, typename EHContainer> struct ResponseHandler;
|
||||
|
||||
template<FunctionHookId functionId, typename ResultType, typename ... ParamTypes>
|
||||
struct ResponseHandler<functionId, ResultType HOOK_CALL (ParamTypes...)> :
|
||||
template<FunctionHookId functionId, typename EHContainerType, typename ResultType, typename ... ParamTypes>
|
||||
struct ResponseHandler<functionId, ResultType HOOK_CALL (ParamTypes...), EHContainerType> :
|
||||
public ResponseHandlerBase
|
||||
{
|
||||
typedef ResultType(HOOK_CALL FunctionType)(ParamTypes...);
|
||||
typedef ResponseHandler<functionId, FunctionType> SelfType;
|
||||
typedef ResponseHandler<functionId, FunctionType, EHContainerType> SelfType;
|
||||
typedef ResponseInfo<functionId> Info;
|
||||
typedef EHContainerType EHContainer;
|
||||
|
||||
static void Marshal(IpdlTuple& aTuple, const ResultType& aResult, const ParamTypes&... aParams)
|
||||
{
|
||||
@ -1215,11 +1041,12 @@ private:
|
||||
* Data for hooking a function that we automatically broker in a remote
|
||||
* process.
|
||||
*/
|
||||
template <FunctionHookId functionId, typename FunctionType>
|
||||
template <FunctionHookId functionId, typename FunctionType,
|
||||
typename EHContainer = BaseEHContainer>
|
||||
class FunctionBroker;
|
||||
|
||||
template <FunctionHookId functionId, typename ResultType, typename ... ParamTypes>
|
||||
class FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...)> :
|
||||
template <FunctionHookId functionId, typename EHContainer, typename ResultType, typename ... ParamTypes>
|
||||
class FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...), EHContainer> :
|
||||
public BasicFunctionHook<functionId, ResultType HOOK_CALL (ParamTypes...)>
|
||||
{
|
||||
public:
|
||||
@ -1230,12 +1057,17 @@ public:
|
||||
static const size_t numParams = sizeof...(ParamTypes);
|
||||
|
||||
typedef ResultType (HOOK_CALL FunctionType)(ParamTypes...);
|
||||
typedef FunctionBroker<functionId, FunctionType> SelfType;
|
||||
typedef FunctionBroker<functionId, FunctionType, EHContainer> SelfType;
|
||||
typedef BasicFunctionHook<functionId, FunctionType> FunctionHookInfoType;
|
||||
typedef FunctionHookInfoType BaseType;
|
||||
|
||||
typedef RequestHandler<functionId, FunctionType> Request;
|
||||
typedef ResponseHandler<functionId, FunctionType> Response;
|
||||
typedef RequestHandler<functionId, FunctionType, EHContainer> Request;
|
||||
typedef ResponseHandler<functionId, FunctionType, EHContainer> Response;
|
||||
|
||||
template <typename DelegateFcnType>
|
||||
using RequestDelegate = RequestHandler<functionId, DelegateFcnType, EHContainer>;
|
||||
template <typename DelegateFcnType>
|
||||
using ResponseDelegate = ResponseHandler<functionId, DelegateFcnType, EHContainer>;
|
||||
|
||||
FunctionBroker(const char* aModuleName, const char* aMethodName,
|
||||
FunctionType* aOriginalFunction) :
|
||||
@ -1327,9 +1159,9 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
template <FunctionHookId functionId, typename ResultType, typename ... ParamTypes>
|
||||
template <FunctionHookId functionId, typename EHContainer, typename ResultType, typename ... ParamTypes>
|
||||
ResultType
|
||||
FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...)>::MaybeBrokerCallClient(ParamTypes&... aParameters) const
|
||||
FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...), EHContainer>::MaybeBrokerCallClient(ParamTypes&... aParameters) const
|
||||
{
|
||||
MOZ_ASSERT(FunctionBrokerChild::GetInstance());
|
||||
|
||||
@ -1364,9 +1196,9 @@ FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...)>::MaybeBrokerCal
|
||||
return FunctionHookInfoType::mOldFunction(aParameters...);
|
||||
}
|
||||
|
||||
template <FunctionHookId functionId, typename ResultType, typename ... ParamTypes>
|
||||
template <FunctionHookId functionId, typename EHContainer, typename ResultType, typename ... ParamTypes>
|
||||
bool
|
||||
FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...)>::BrokerCallClient(uint32_t& aWinError,
|
||||
FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...), EHContainer>::BrokerCallClient(uint32_t& aWinError,
|
||||
ResultType& aResult,
|
||||
ParamTypes&... aParameters) const
|
||||
{
|
||||
@ -1411,9 +1243,9 @@ FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...)>::BrokerCallClie
|
||||
return false;
|
||||
}
|
||||
|
||||
template <FunctionHookId functionId, typename ResultType, typename ... ParamTypes>
|
||||
template <FunctionHookId functionId, typename EHContainer, typename ResultType, typename ... ParamTypes>
|
||||
bool
|
||||
FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...)>::BrokerCallServer(base::ProcessId aClientId, const IpdlTuple &aInTuple,
|
||||
FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...), EHContainer>::BrokerCallServer(base::ProcessId aClientId, const IpdlTuple &aInTuple,
|
||||
IpdlTuple *aOutTuple, ParamTypes&... aParams) const
|
||||
{
|
||||
HOOK_LOG(LogLevel::Info, ("[%s] Server brokering function.", FunctionHookInfoType::mFunctionName.Data()));
|
||||
@ -1459,9 +1291,9 @@ FunctionBroker<functionId, ResultType HOOK_CALL (ParamTypes...)>::BrokerCallServ
|
||||
return true;
|
||||
}
|
||||
|
||||
template <FunctionHookId functionId, typename ResultType, typename ... ParamTypes>
|
||||
template <FunctionHookId functionId, typename EHContainer, typename ResultType, typename ... ParamTypes>
|
||||
bool
|
||||
FunctionBroker<functionId,ResultType HOOK_CALL (ParamTypes...)>::
|
||||
FunctionBroker<functionId,ResultType HOOK_CALL (ParamTypes...), EHContainer>::
|
||||
PostToDispatchThread(uint32_t& aWinError, ResultType& aRet,
|
||||
ParamTypes&... aParameters) const
|
||||
{
|
||||
|
@ -46,6 +46,7 @@ enum FunctionHookId
|
||||
, ID_QueryCredentialsAttributesA
|
||||
, ID_FreeCredentialsHandle
|
||||
, ID_PrintDlgW
|
||||
, ID_CreateMutexW
|
||||
, ID_FunctionHookCount
|
||||
#else // defined(XP_WIN)
|
||||
ID_FunctionHookCount
|
||||
|
@ -61,6 +61,12 @@ PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchComple
|
||||
// On Mac, when |aSandboxLevel| is positive, we enable the sandbox.
|
||||
#if defined(XP_WIN)
|
||||
mSandboxLevel = aSandboxLevel;
|
||||
|
||||
// The sandbox process sometimes needs read access to the plugin file.
|
||||
if (aSandboxLevel >= 3) {
|
||||
std::wstring pluginFile(NS_ConvertUTF8toUTF16(mPluginFilePath.c_str()).get());
|
||||
mAllowedFilesRead.push_back(pluginFile);
|
||||
}
|
||||
#endif // XP_WIN
|
||||
#else
|
||||
if (aSandboxLevel != 0) {
|
||||
|
@ -31,6 +31,7 @@ int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType,
|
||||
quirks |= QUIRK_FLASH_HOOK_GETKEYSTATE;
|
||||
quirks |= QUIRK_FLASH_HOOK_PRINTDLGW;
|
||||
quirks |= QUIRK_FLASH_HOOK_SSL;
|
||||
quirks |= QUIRK_FLASH_HOOK_CREATEMUTEXW;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ enum PluginQuirks {
|
||||
QUIRK_FLASH_HOOK_PRINTDLGW = 1 << 14,
|
||||
// Win: Broker Win32 SSL operations
|
||||
QUIRK_FLASH_HOOK_SSL = 1 << 15,
|
||||
// Win: Hook CreateMutexW for brokering when using the camera
|
||||
QUIRK_FLASH_HOOK_CREATEMUTEXW = 1 << 16,
|
||||
};
|
||||
|
||||
int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType,
|
||||
|
@ -304,12 +304,14 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULElement)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULElement,
|
||||
nsStyledElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBindingParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULElement,
|
||||
nsStyledElement)
|
||||
// Why aren't we unlinking the prototype?
|
||||
tmp->ClearHasID();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBindingParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsXULElement, nsStyledElement)
|
||||
|
@ -670,9 +670,9 @@ protected:
|
||||
|
||||
/**
|
||||
* The nearest enclosing content node with a binding
|
||||
* that created us. [Weak]
|
||||
* that created us.
|
||||
*/
|
||||
nsIContent* mBindingParent;
|
||||
nsCOMPtr<nsIContent> mBindingParent;
|
||||
|
||||
/**
|
||||
* Abandon our prototype linkage, and copy all attributes locally
|
||||
|
@ -68,8 +68,13 @@ struct null_t {
|
||||
|
||||
struct SerializedStructuredCloneBuffer final
|
||||
{
|
||||
SerializedStructuredCloneBuffer() {}
|
||||
SerializedStructuredCloneBuffer()
|
||||
: data(JS::StructuredCloneScope::Unassigned)
|
||||
{
|
||||
}
|
||||
|
||||
SerializedStructuredCloneBuffer(const SerializedStructuredCloneBuffer& aOther)
|
||||
: SerializedStructuredCloneBuffer()
|
||||
{
|
||||
*this = aOther;
|
||||
}
|
||||
@ -78,6 +83,7 @@ struct SerializedStructuredCloneBuffer final
|
||||
operator=(const SerializedStructuredCloneBuffer& aOther)
|
||||
{
|
||||
data.Clear();
|
||||
data.initScope(aOther.data.scope());
|
||||
data.Append(aOther.data);
|
||||
return *this;
|
||||
}
|
||||
@ -876,7 +882,7 @@ struct ParamTraits<JSStructuredCloneData>
|
||||
return false;
|
||||
}
|
||||
|
||||
*aResult = JSStructuredCloneData(Move(out));
|
||||
*aResult = JSStructuredCloneData(Move(out), JS::StructuredCloneScope::DifferentProcess);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -168,7 +168,14 @@ enum class StructuredCloneScope : uint32_t {
|
||||
*
|
||||
* Do not use this for writing; use DifferentProcess instead.
|
||||
*/
|
||||
DifferentProcessForIndexedDB
|
||||
DifferentProcessForIndexedDB,
|
||||
|
||||
/**
|
||||
* Existing code wants to be able to create an uninitialized
|
||||
* JSStructuredCloneData without knowing the scope, then populate it with
|
||||
* data (at which point the scope *is* known.)
|
||||
*/
|
||||
Unassigned
|
||||
};
|
||||
|
||||
enum TransferableOwnership {
|
||||
@ -387,6 +394,11 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
|
||||
BufferList bufList_;
|
||||
|
||||
// The (address space, thread) scope within which this clone is valid. Note
|
||||
// that this must be either set during construction, or start out as
|
||||
// Unassigned and transition once to something else.
|
||||
JS::StructuredCloneScope scope_;
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks_ = nullptr;
|
||||
void* closure_ = nullptr;
|
||||
OwnTransferablePolicy ownTransferables_ = OwnTransferablePolicy::NoTransferables;
|
||||
@ -399,8 +411,9 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
public:
|
||||
// The constructor must be infallible but SystemAllocPolicy is not, so both
|
||||
// the initial size and initial capacity of the BufferList must be zero.
|
||||
explicit JSStructuredCloneData()
|
||||
explicit JSStructuredCloneData(JS::StructuredCloneScope scope)
|
||||
: bufList_(0, 0, kStandardCapacity, js::SystemAllocPolicy())
|
||||
, scope_(scope)
|
||||
, callbacks_(nullptr)
|
||||
, closure_(nullptr)
|
||||
, ownTransferables_(OwnTransferablePolicy::NoTransferables)
|
||||
@ -408,12 +421,16 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
|
||||
// Steal the raw data from a BufferList. In this case, we don't know the
|
||||
// scope and none of the callback info is assigned yet.
|
||||
MOZ_IMPLICIT JSStructuredCloneData(BufferList&& buffers)
|
||||
JSStructuredCloneData(BufferList&& buffers, JS::StructuredCloneScope scope)
|
||||
: bufList_(mozilla::Move(buffers))
|
||||
, scope_(scope)
|
||||
, callbacks_(nullptr)
|
||||
, closure_(nullptr)
|
||||
, ownTransferables_(OwnTransferablePolicy::NoTransferables)
|
||||
{}
|
||||
MOZ_IMPLICIT JSStructuredCloneData(BufferList&& buffers)
|
||||
: JSStructuredCloneData(mozilla::Move(buffers), JS::StructuredCloneScope::Unassigned)
|
||||
{}
|
||||
JSStructuredCloneData(JSStructuredCloneData&& other) = default;
|
||||
JSStructuredCloneData& operator=(JSStructuredCloneData&& other) = default;
|
||||
~JSStructuredCloneData() { discardTransferables(); }
|
||||
@ -429,6 +446,15 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
|
||||
bool Init(size_t initialCapacity = 0) { return bufList_.Init(0, initialCapacity); }
|
||||
|
||||
JS::StructuredCloneScope scope() const { return scope_; }
|
||||
|
||||
void initScope(JS::StructuredCloneScope scope) {
|
||||
MOZ_ASSERT(Size() == 0, "initScope() of nonempty JSStructuredCloneData");
|
||||
if (scope_ != JS::StructuredCloneScope::Unassigned)
|
||||
MOZ_ASSERT(scope_ == scope, "Cannot change scope after it has been initialized");
|
||||
scope_ = scope;
|
||||
}
|
||||
|
||||
size_t Size() const { return bufList_.Size(); }
|
||||
|
||||
const Iterator Start() const { return bufList_.Iter(); }
|
||||
@ -443,12 +469,14 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
|
||||
// Append new data to the end of the buffer.
|
||||
bool AppendBytes(const char* data, size_t size) {
|
||||
MOZ_ASSERT(scope_ != JS::StructuredCloneScope::Unassigned);
|
||||
return bufList_.WriteBytes(data, size);
|
||||
}
|
||||
|
||||
// Update data stored within the existing buffer. There must be at least
|
||||
// 'size' bytes between the position of 'iter' and the end of the buffer.
|
||||
bool UpdateBytes(Iterator& iter, const char* data, size_t size) const {
|
||||
MOZ_ASSERT(scope_ != JS::StructuredCloneScope::Unassigned);
|
||||
while (size > 0) {
|
||||
size_t remaining = iter.RemainingInSegment();
|
||||
size_t nbytes = std::min(remaining, size);
|
||||
@ -469,11 +497,15 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
bufList_.Clear();
|
||||
}
|
||||
|
||||
template<typename BorrowingAllocPolicy>
|
||||
mozilla::BufferList<BorrowingAllocPolicy> Borrow(Iterator& iter, size_t size, bool* success,
|
||||
BorrowingAllocPolicy ap = BorrowingAllocPolicy()) const
|
||||
// Return a new read-only JSStructuredCloneData that "borrows" the contents
|
||||
// of |this|. Its lifetime should not exceed the donor's. This is only
|
||||
// allowed for DifferentProcess clones, so finalization of the borrowing
|
||||
// clone will do nothing.
|
||||
JSStructuredCloneData Borrow(Iterator& iter, size_t size, bool* success) const
|
||||
{
|
||||
return bufList_.Borrow<BorrowingAllocPolicy>(iter, size, success);
|
||||
MOZ_ASSERT(scope_ == JS::StructuredCloneScope::DifferentProcess);
|
||||
return JSStructuredCloneData(bufList_.Borrow<js::SystemAllocPolicy>(iter, size, success),
|
||||
scope_);
|
||||
}
|
||||
|
||||
// Iterate over all contained data, one BufferList segment's worth at a
|
||||
@ -493,6 +525,7 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
|
||||
// Append the entire contents of other's bufList_ to our own.
|
||||
bool Append(const JSStructuredCloneData& other) {
|
||||
MOZ_ASSERT(scope_ == other.scope());
|
||||
return other.ForEachDataChunk([&](const char* data, size_t size) {
|
||||
return AppendBytes(data, size);
|
||||
});
|
||||
@ -502,11 +535,6 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API(JSStructuredCloneData) {
|
||||
return bufList_.SizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
// For testing only.
|
||||
void IgnoreTransferables() {
|
||||
ownTransferables_ = OwnTransferablePolicy::IgnoreTransferablesIfAny;
|
||||
}
|
||||
|
||||
void discardTransferables();
|
||||
};
|
||||
|
||||
@ -563,7 +591,7 @@ class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) {
|
||||
public:
|
||||
JSAutoStructuredCloneBuffer(JS::StructuredCloneScope scope,
|
||||
const JSStructuredCloneCallbacks* callbacks, void* closure)
|
||||
: scope_(scope), version_(JS_STRUCTURED_CLONE_VERSION)
|
||||
: scope_(scope), data_(scope), version_(JS_STRUCTURED_CLONE_VERSION)
|
||||
{
|
||||
data_.setCallbacks(callbacks, closure, OwnTransferablePolicy::NoTransferables);
|
||||
}
|
||||
@ -578,6 +606,8 @@ class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) {
|
||||
|
||||
void clear();
|
||||
|
||||
JS::StructuredCloneScope scope() const { return scope_; }
|
||||
|
||||
/**
|
||||
* Adopt some memory. It will be automatically freed by the destructor.
|
||||
* data must have been allocated by the JS engine (e.g., extracted via
|
||||
|
@ -2845,7 +2845,7 @@ class CloneBufferObject : public NativeObject {
|
||||
Rooted<CloneBufferObject*> obj(cx, Create(cx));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
auto data = js::MakeUnique<JSStructuredCloneData>();
|
||||
auto data = js::MakeUnique<JSStructuredCloneData>(buffer->scope());
|
||||
if (!data) {
|
||||
ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
@ -2867,11 +2867,6 @@ class CloneBufferObject : public NativeObject {
|
||||
MOZ_ASSERT(!data());
|
||||
setReservedSlot(DATA_SLOT, PrivateValue(aData));
|
||||
setReservedSlot(SYNTHETIC_SLOT, BooleanValue(synthetic));
|
||||
|
||||
// For testing only, and will be unnecessary once the scope is moved
|
||||
// into JSStructuredCloneData.
|
||||
if (synthetic)
|
||||
aData->IgnoreTransferables();
|
||||
}
|
||||
|
||||
// Discard an owned clone buffer.
|
||||
@ -2909,7 +2904,7 @@ class CloneBufferObject : public NativeObject {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto buf = js::MakeUnique<JSStructuredCloneData>();
|
||||
auto buf = js::MakeUnique<JSStructuredCloneData>(JS::StructuredCloneScope::DifferentProcess);
|
||||
if (!buf || !buf->Init(nbytes)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
|
@ -39,7 +39,9 @@ testStructuredCloneReaderFuzz(const uint8_t* buf, size_t size) {
|
||||
const size_t kSegmentAlignment = 8;
|
||||
size_t buf_size = JS_ROUNDUP(size, kSegmentAlignment);
|
||||
|
||||
auto clonebuf = MakeUnique<JSStructuredCloneData>();
|
||||
JS::StructuredCloneScope scope = JS::StructuredCloneScope::DifferentProcess;
|
||||
|
||||
auto clonebuf = MakeUnique<JSStructuredCloneData>(scope);
|
||||
if (!clonebuf || !clonebuf->Init(buf_size)) {
|
||||
ReportOutOfMemory(gCx);
|
||||
return 0;
|
||||
@ -50,8 +52,6 @@ testStructuredCloneReaderFuzz(const uint8_t* buf, size_t size) {
|
||||
char padding[kSegmentAlignment] = {0};
|
||||
clonebuf->AppendBytes(padding, buf_size - size);
|
||||
|
||||
JS::StructuredCloneScope scope = JS::StructuredCloneScope::DifferentProcess;
|
||||
|
||||
RootedValue deserialized(gCx);
|
||||
if (!JS_ReadStructuredClone(gCx, *clonebuf,
|
||||
JS_STRUCTURED_CLONE_VERSION,
|
||||
|
@ -1267,14 +1267,8 @@ CodeGenerator::visitValueToObjectOrNull(LValueToObjectOrNull* lir)
|
||||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
enum class FieldToBarrier {
|
||||
REGEXP_PENDING_INPUT,
|
||||
REGEXP_MATCHES_INPUT,
|
||||
DEPENDENT_STRING_BASE
|
||||
};
|
||||
|
||||
static void
|
||||
EmitStoreBufferMutation(MacroAssembler& masm, Register holder, FieldToBarrier field,
|
||||
EmitStoreBufferMutation(MacroAssembler& masm, Register holder, size_t offset,
|
||||
Register buffer,
|
||||
LiveGeneralRegisterSet& liveVolatiles,
|
||||
void (*fun)(js::gc::StoreBuffer*, js::gc::Cell**))
|
||||
@ -1293,19 +1287,7 @@ EmitStoreBufferMutation(MacroAssembler& masm, Register holder, FieldToBarrier fi
|
||||
regs.takeUnchecked(holder);
|
||||
Register addrReg = regs.takeAny();
|
||||
|
||||
switch (field) {
|
||||
case FieldToBarrier::REGEXP_PENDING_INPUT:
|
||||
masm.computeEffectiveAddress(Address(holder, RegExpStatics::offsetOfPendingInput()), addrReg);
|
||||
break;
|
||||
|
||||
case FieldToBarrier::REGEXP_MATCHES_INPUT:
|
||||
masm.computeEffectiveAddress(Address(holder, RegExpStatics::offsetOfMatchesInput()), addrReg);
|
||||
break;
|
||||
|
||||
case FieldToBarrier::DEPENDENT_STRING_BASE:
|
||||
masm.leaNewDependentStringBase(holder, addrReg);
|
||||
break;
|
||||
}
|
||||
masm.computeEffectiveAddress(Address(holder, offset), addrReg);
|
||||
|
||||
bool needExtraReg = !regs.hasAny<GeneralRegisterSet::DefaultType>();
|
||||
if (needExtraReg) {
|
||||
@ -1328,7 +1310,7 @@ EmitStoreBufferMutation(MacroAssembler& masm, Register holder, FieldToBarrier fi
|
||||
// Warning: this function modifies prev and next.
|
||||
static void
|
||||
EmitPostWriteBarrierS(MacroAssembler& masm,
|
||||
Register string, FieldToBarrier field,
|
||||
Register holder, size_t offset,
|
||||
Register prev, Register next,
|
||||
LiveGeneralRegisterSet& liveVolatiles)
|
||||
{
|
||||
@ -1348,7 +1330,7 @@ EmitPostWriteBarrierS(MacroAssembler& masm,
|
||||
|
||||
// buffer->putCell(cellp)
|
||||
masm.bind(&putCell);
|
||||
EmitStoreBufferMutation(masm, string, field, storebuffer, liveVolatiles,
|
||||
EmitStoreBufferMutation(masm, holder, offset, storebuffer, liveVolatiles,
|
||||
JSString::addCellAddressToStoreBuffer);
|
||||
masm.jump(&exit);
|
||||
|
||||
@ -1357,7 +1339,7 @@ EmitPostWriteBarrierS(MacroAssembler& masm,
|
||||
masm.branchPtr(Assembler::Equal, prev, ImmWord(0), &exit);
|
||||
masm.loadStoreBuffer(prev, storebuffer);
|
||||
masm.branchPtr(Assembler::Equal, storebuffer, ImmWord(0), &exit);
|
||||
EmitStoreBufferMutation(masm, string, field, storebuffer, liveVolatiles,
|
||||
EmitStoreBufferMutation(masm, holder, offset, storebuffer, liveVolatiles,
|
||||
JSString::removeCellAddressFromStoreBuffer);
|
||||
|
||||
masm.bind(&exit);
|
||||
@ -1414,6 +1396,7 @@ PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Re
|
||||
Register temp1, Register temp2, Register temp3,
|
||||
size_t inputOutputDataStartOffset,
|
||||
RegExpShared::CompilationMode mode,
|
||||
bool stringsCanBeInNursery,
|
||||
Label* notFound, Label* failure)
|
||||
{
|
||||
size_t matchPairsStartOffset = inputOutputDataStartOffset + sizeof(irregexp::InputOutputData);
|
||||
@ -1609,21 +1592,26 @@ PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Re
|
||||
masm.guardedCallPreBarrier(matchesInputAddress, MIRType::String);
|
||||
masm.guardedCallPreBarrier(lazySourceAddress, MIRType::String);
|
||||
|
||||
if (temp1.volatile_())
|
||||
volatileRegs.add(temp1);
|
||||
if (stringsCanBeInNursery) {
|
||||
// Writing into RegExpStatics tenured memory; must post-barrier.
|
||||
if (temp1.volatile_())
|
||||
volatileRegs.add(temp1);
|
||||
|
||||
// Writing into RegExpStatics tenured memory; must post-barrier.
|
||||
masm.loadPtr(pendingInputAddress, temp2);
|
||||
masm.storePtr(input, pendingInputAddress);
|
||||
masm.movePtr(input, temp3);
|
||||
EmitPostWriteBarrierS(masm, temp1, FieldToBarrier::REGEXP_PENDING_INPUT,
|
||||
temp2 /* prev */, temp3 /* next */, volatileRegs);
|
||||
masm.loadPtr(pendingInputAddress, temp2);
|
||||
masm.storePtr(input, pendingInputAddress);
|
||||
masm.movePtr(input, temp3);
|
||||
EmitPostWriteBarrierS(masm, temp1, RegExpStatics::offsetOfPendingInput(),
|
||||
temp2 /* prev */, temp3 /* next */, volatileRegs);
|
||||
|
||||
masm.loadPtr(matchesInputAddress, temp2);
|
||||
masm.storePtr(input, matchesInputAddress);
|
||||
masm.movePtr(input, temp3);
|
||||
EmitPostWriteBarrierS(masm, temp1, FieldToBarrier::REGEXP_MATCHES_INPUT,
|
||||
temp2 /* prev */, temp3 /* next */, volatileRegs);
|
||||
masm.loadPtr(matchesInputAddress, temp2);
|
||||
masm.storePtr(input, matchesInputAddress);
|
||||
masm.movePtr(input, temp3);
|
||||
EmitPostWriteBarrierS(masm, temp1, RegExpStatics::offsetOfMatchesInput(),
|
||||
temp2 /* prev */, temp3 /* next */, volatileRegs);
|
||||
} else {
|
||||
masm.storePtr(input, pendingInputAddress);
|
||||
masm.storePtr(input, matchesInputAddress);
|
||||
}
|
||||
|
||||
masm.storePtr(lastIndex, Address(temp1, RegExpStatics::offsetOfLazyIndex()));
|
||||
masm.store32(Imm32(1), Address(temp1, RegExpStatics::offsetOfPendingLazyEvaluation()));
|
||||
@ -1664,6 +1652,7 @@ public:
|
||||
// Caller should call generateFallback after masm.ret(), to generate
|
||||
// fallback path.
|
||||
void generate(MacroAssembler& masm, const JSAtomState& names,
|
||||
CompileRuntime* runtime,
|
||||
bool latin1, Register string,
|
||||
Register base, Register temp1, Register temp2,
|
||||
BaseIndex startIndexAddress, BaseIndex limitIndexAddress,
|
||||
@ -1676,6 +1665,7 @@ public:
|
||||
|
||||
void
|
||||
CreateDependentString::generate(MacroAssembler& masm, const JSAtomState& names,
|
||||
CompileRuntime* runtime,
|
||||
bool latin1, Register string,
|
||||
Register base, Register temp1, Register temp2,
|
||||
BaseIndex startIndexAddress, BaseIndex limitIndexAddress,
|
||||
@ -1802,14 +1792,23 @@ CreateDependentString::generate(MacroAssembler& masm, const JSAtomState& names,
|
||||
|
||||
// Post-barrier the base store, whether it was the direct or indirect
|
||||
// base (both will end up in temp1 here).
|
||||
masm.movePtr(ImmWord(0), temp2);
|
||||
LiveGeneralRegisterSet saveRegs(GeneralRegisterSet::Volatile());
|
||||
if (temp1.volatile_())
|
||||
saveRegs.takeUnchecked(temp1);
|
||||
if (temp2.volatile_())
|
||||
saveRegs.takeUnchecked(temp2);
|
||||
EmitPostWriteBarrierS(masm, string, FieldToBarrier::DEPENDENT_STRING_BASE,
|
||||
temp2 /* prev */, temp1 /* next */, saveRegs);
|
||||
masm.branchPtrInNurseryChunk(Assembler::NotEqual, temp1, temp2, &done);
|
||||
|
||||
LiveRegisterSet regsToSave(RegisterSet::Volatile());
|
||||
regsToSave.takeUnchecked(temp1);
|
||||
regsToSave.takeUnchecked(temp2);
|
||||
regsToSave.addUnchecked(string);
|
||||
|
||||
masm.PushRegsInMask(regsToSave);
|
||||
|
||||
masm.mov(ImmPtr(runtime), temp1);
|
||||
|
||||
masm.setupUnalignedABICall(temp2);
|
||||
masm.passABIArg(temp1);
|
||||
masm.passABIArg(string);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, PostWriteBarrier));
|
||||
|
||||
masm.PopRegsInMask(regsToSave);
|
||||
}
|
||||
|
||||
masm.bind(&done);
|
||||
@ -1947,7 +1946,7 @@ JitCompartment::generateRegExpMatcherStub(JSContext* cx)
|
||||
Label notFound, oolEntry;
|
||||
if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex,
|
||||
temp1, temp2, temp5, inputOutputDataStartOffset,
|
||||
RegExpShared::Normal, ¬Found, &oolEntry))
|
||||
RegExpShared::Normal, stringsCanBeInNursery, ¬Found, &oolEntry))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -2033,7 +2032,9 @@ JitCompartment::generateRegExpMatcherStub(JSContext* cx)
|
||||
Label isUndefined, storeDone;
|
||||
masm.branch32(Assembler::LessThan, stringIndexAddress, Imm32(0), &isUndefined);
|
||||
|
||||
depStr[isLatin].generate(masm, cx->names(), isLatin, temp3, input, temp4, temp5,
|
||||
depStr[isLatin].generate(masm, cx->names(),
|
||||
CompileRuntime::get(cx->runtime()),
|
||||
isLatin, temp3, input, temp4, temp5,
|
||||
stringIndexAddress, stringLimitAddress,
|
||||
stringsCanBeInNursery,
|
||||
failure);
|
||||
@ -2254,7 +2255,8 @@ JitCompartment::generateRegExpSearcherStub(JSContext* cx)
|
||||
Label notFound, oolEntry;
|
||||
if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex,
|
||||
temp1, temp2, temp3, inputOutputDataStartOffset,
|
||||
RegExpShared::Normal, ¬Found, &oolEntry))
|
||||
RegExpShared::Normal, stringsCanBeInNursery,
|
||||
¬Found, &oolEntry))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -2406,7 +2408,8 @@ JitCompartment::generateRegExpTesterStub(JSContext* cx)
|
||||
Label notFound, oolEntry;
|
||||
if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex,
|
||||
temp1, temp2, temp3, 0,
|
||||
RegExpShared::MatchOnly, ¬Found, &oolEntry))
|
||||
RegExpShared::MatchOnly, stringsCanBeInNursery,
|
||||
¬Found, &oolEntry))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -3977,11 +3980,13 @@ EmitPostWriteBarrier(MacroAssembler& masm, CompileRuntime* runtime, Register obj
|
||||
Register runtimereg = regs.takeAny();
|
||||
masm.mov(ImmPtr(runtime), runtimereg);
|
||||
|
||||
void (*fun)(JSRuntime*, JSObject*) = isGlobal ? PostGlobalWriteBarrier : PostWriteBarrier;
|
||||
masm.setupUnalignedABICall(regs.takeAny());
|
||||
masm.passABIArg(runtimereg);
|
||||
masm.passABIArg(objreg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, fun));
|
||||
if (isGlobal)
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, PostGlobalWriteBarrier));
|
||||
else
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, PostWriteBarrier));
|
||||
|
||||
masm.bind(&exit);
|
||||
}
|
||||
|
@ -689,11 +689,11 @@ GetDynamicName(JSContext* cx, JSObject* envChain, JSString* str, Value* vp)
|
||||
}
|
||||
|
||||
void
|
||||
PostWriteBarrier(JSRuntime* rt, JSObject* obj)
|
||||
PostWriteBarrier(JSRuntime* rt, js::gc::Cell* cell)
|
||||
{
|
||||
AutoUnsafeCallWithABI unsafe;
|
||||
MOZ_ASSERT(!IsInsideNursery(obj));
|
||||
rt->gc.storeBuffer().putWholeCell(obj);
|
||||
MOZ_ASSERT(!IsInsideNursery(cell));
|
||||
rt->gc.storeBuffer().putWholeCell(cell);
|
||||
}
|
||||
|
||||
static const size_t MAX_WHOLE_CELL_BUFFER_SIZE = 4096;
|
||||
|
@ -25,6 +25,12 @@ class GeneratorObject;
|
||||
class RegExpObject;
|
||||
class TypedArrayObject;
|
||||
|
||||
namespace gc {
|
||||
|
||||
struct Cell;
|
||||
|
||||
}
|
||||
|
||||
namespace jit {
|
||||
|
||||
enum DataType : uint8_t {
|
||||
@ -744,7 +750,7 @@ CreateThis(JSContext* cx, HandleObject callee, HandleObject newTarget, MutableHa
|
||||
|
||||
void GetDynamicName(JSContext* cx, JSObject* scopeChain, JSString* str, Value* vp);
|
||||
|
||||
void PostWriteBarrier(JSRuntime* rt, JSObject* obj);
|
||||
void PostWriteBarrier(JSRuntime* rt, js::gc::Cell* cell);
|
||||
void PostGlobalWriteBarrier(JSRuntime* rt, JSObject* obj);
|
||||
|
||||
enum class IndexInBounds { Yes, Maybe };
|
||||
|
@ -49,19 +49,18 @@ template <typename CharT>
|
||||
static uint32_t
|
||||
HashStringChars(JSString* s)
|
||||
{
|
||||
ScopedJSFreePtr<CharT> ownedChars;
|
||||
const CharT* chars;
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
uint32_t hash = 0;
|
||||
if (s->isLinear()) {
|
||||
chars = s->asLinear().chars<CharT>(nogc);
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
const CharT* chars = s->asLinear().chars<CharT>(nogc);
|
||||
hash = mozilla::HashString(chars, s->length());
|
||||
} else {
|
||||
// Slowest hash function evar!
|
||||
if (!s->asRope().copyChars<CharT>(/* tcx */ nullptr, ownedChars))
|
||||
// Use rope's non-copying hash function.
|
||||
if (!s->asRope().hash(&hash))
|
||||
MOZ_CRASH("oom");
|
||||
chars = ownedChars;
|
||||
}
|
||||
|
||||
return mozilla::HashString(chars, s->length());
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* static */ HashNumber
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "vm/StringType-inl.h"
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
@ -345,6 +346,53 @@ JSRope::copyCharsInternal(JSContext* cx, ScopedJSFreePtr<CharT>& out,
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
void AddStringToHash(uint32_t* hash, const CharT* chars, size_t len)
|
||||
{
|
||||
// It's tempting to use |HashString| instead of this loop, but that's
|
||||
// slightly different than our existing implementation for non-ropes. We
|
||||
// want to pretend we have a contiguous set of chars so we need to
|
||||
// accumulate char by char rather than generate a new hash for substring
|
||||
// and then accumulate that.
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
*hash = mozilla::AddToHash(*hash, chars[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void AddStringToHash(uint32_t* hash, const JSString* str)
|
||||
{
|
||||
AutoCheckCannotGC nogc;
|
||||
const auto& s = str->asLinear();
|
||||
if (s.hasLatin1Chars())
|
||||
AddStringToHash(hash, s.latin1Chars(nogc), s.length());
|
||||
else
|
||||
AddStringToHash(hash, s.twoByteChars(nogc), s.length());
|
||||
}
|
||||
|
||||
bool
|
||||
JSRope::hash(uint32_t* outHash) const
|
||||
{
|
||||
Vector<const JSString*, 8, SystemAllocPolicy> nodeStack;
|
||||
const JSString* str = this;
|
||||
|
||||
*outHash = 0;
|
||||
|
||||
while (true) {
|
||||
if (str->isRope()) {
|
||||
if (!nodeStack.append(str->asRope().rightChild()))
|
||||
return false;
|
||||
str = str->asRope().leftChild();
|
||||
} else {
|
||||
AddStringToHash(outHash, str);
|
||||
if (nodeStack.empty())
|
||||
break;
|
||||
str = nodeStack.popCopy();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
JSRope::dumpRepresentation(js::GenericPrinter& out, int indent) const
|
||||
|
@ -700,6 +700,13 @@ class JSRope : public JSString
|
||||
template <typename CharT>
|
||||
bool copyChars(JSContext* cx, js::ScopedJSFreePtr<CharT>& out) const;
|
||||
|
||||
// Hash function specific for ropes that avoids allocating a temporary
|
||||
// string. There are still allocations internally so it's technically
|
||||
// fallible.
|
||||
//
|
||||
// Returns the same value as if this were a linear string being hashed.
|
||||
MOZ_MUST_USE bool hash(uint32_t* outhHash) const;
|
||||
|
||||
JSString* leftChild() const {
|
||||
MOZ_ASSERT(isRope());
|
||||
return d.s.u2.left;
|
||||
|
@ -306,9 +306,10 @@ struct SCOutput {
|
||||
public:
|
||||
using Iter = BufferIterator<uint64_t, SystemAllocPolicy>;
|
||||
|
||||
explicit SCOutput(JSContext* cx);
|
||||
SCOutput(JSContext* cx, JS::StructuredCloneScope scope);
|
||||
|
||||
JSContext* context() const { return cx; }
|
||||
JS::StructuredCloneScope scope() const { return buf.scope(); }
|
||||
|
||||
MOZ_MUST_USE bool write(uint64_t u);
|
||||
MOZ_MUST_USE bool writePair(uint32_t tag, uint32_t data);
|
||||
@ -463,7 +464,7 @@ struct JSStructuredCloneWriter {
|
||||
const JSStructuredCloneCallbacks* cb,
|
||||
void* cbClosure,
|
||||
const Value& tVal)
|
||||
: out(cx), scope(scope), objs(out.context()),
|
||||
: out(cx, scope), objs(out.context()),
|
||||
counts(out.context()), entries(out.context()),
|
||||
memory(out.context()),
|
||||
transferable(out.context(), tVal),
|
||||
@ -491,8 +492,6 @@ struct JSStructuredCloneWriter {
|
||||
out.extractBuffer(newData);
|
||||
}
|
||||
|
||||
JS::StructuredCloneScope cloneScope() const { return scope; }
|
||||
|
||||
private:
|
||||
JSStructuredCloneWriter() = delete;
|
||||
JSStructuredCloneWriter(const JSStructuredCloneWriter&) = delete;
|
||||
@ -524,9 +523,6 @@ struct JSStructuredCloneWriter {
|
||||
|
||||
SCOutput out;
|
||||
|
||||
// The (address space, thread) scope within which this clone is valid.
|
||||
JS::StructuredCloneScope scope;
|
||||
|
||||
// Vector of objects with properties remaining to be written.
|
||||
//
|
||||
// NB: These can span multiple compartments, so the compartment must be
|
||||
@ -633,81 +629,6 @@ ReadStructuredClone(JSContext* cx, JSStructuredCloneData& data,
|
||||
return r.read(vp);
|
||||
}
|
||||
|
||||
// If the given buffer contains Transferables, free them. Note that custom
|
||||
// Transferables will use the JSStructuredCloneCallbacks::freeTransfer() to
|
||||
// delete their transferables.
|
||||
template<typename AllocPolicy>
|
||||
static void
|
||||
DiscardTransferables(mozilla::BufferList<AllocPolicy>& buffer,
|
||||
const JSStructuredCloneCallbacks* cb, void* cbClosure)
|
||||
{
|
||||
auto point = BufferIterator<uint64_t, AllocPolicy>(buffer);
|
||||
if (point.done())
|
||||
return; // Empty buffer
|
||||
|
||||
uint32_t tag, data;
|
||||
MOZ_RELEASE_ASSERT(point.canPeek());
|
||||
SCInput::getPair(point.peek(), &tag, &data);
|
||||
point.next();
|
||||
|
||||
if (tag == SCTAG_HEADER) {
|
||||
if (point.done())
|
||||
return;
|
||||
|
||||
MOZ_RELEASE_ASSERT(point.canPeek());
|
||||
SCInput::getPair(point.peek(), &tag, &data);
|
||||
point.next();
|
||||
}
|
||||
|
||||
if (tag != SCTAG_TRANSFER_MAP_HEADER)
|
||||
return;
|
||||
|
||||
if (TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED)
|
||||
return;
|
||||
|
||||
// freeTransfer should not GC
|
||||
JS::AutoSuppressGCAnalysis nogc;
|
||||
|
||||
if (point.done())
|
||||
return;
|
||||
|
||||
uint64_t numTransferables = NativeEndian::swapFromLittleEndian(point.peek());
|
||||
point.next();
|
||||
while (numTransferables--) {
|
||||
if (!point.canPeek())
|
||||
return;
|
||||
|
||||
uint32_t ownership;
|
||||
SCInput::getPair(point.peek(), &tag, &ownership);
|
||||
point.next();
|
||||
MOZ_ASSERT(tag >= SCTAG_TRANSFER_MAP_PENDING_ENTRY);
|
||||
if (!point.canPeek())
|
||||
return;
|
||||
|
||||
void* content;
|
||||
SCInput::getPtr(point.peek(), &content);
|
||||
point.next();
|
||||
if (!point.canPeek())
|
||||
return;
|
||||
|
||||
uint64_t extraData = NativeEndian::swapFromLittleEndian(point.peek());
|
||||
point.next();
|
||||
|
||||
if (ownership < JS::SCTAG_TMO_FIRST_OWNED)
|
||||
continue;
|
||||
|
||||
if (ownership == JS::SCTAG_TMO_ALLOC_DATA) {
|
||||
js_free(content);
|
||||
} else if (ownership == JS::SCTAG_TMO_MAPPED_DATA) {
|
||||
JS_ReleaseMappedArrayBufferContents(content, extraData);
|
||||
} else if (cb && cb->freeTransfer) {
|
||||
cb->freeTransfer(tag, JS::TransferableOwnership(ownership), content, extraData, cbClosure);
|
||||
} else {
|
||||
MOZ_ASSERT(false, "unknown ownership");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
StructuredCloneHasTransferObjects(const JSStructuredCloneData& data)
|
||||
{
|
||||
@ -897,8 +818,8 @@ SCInput::readPtr(void** p)
|
||||
return true;
|
||||
}
|
||||
|
||||
SCOutput::SCOutput(JSContext* cx)
|
||||
: cx(cx)
|
||||
SCOutput::SCOutput(JSContext* cx, JS::StructuredCloneScope scope)
|
||||
: cx(cx), buf(scope)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1019,13 +940,92 @@ SCOutput::discardTransferables()
|
||||
} // namespace js
|
||||
|
||||
|
||||
// If the buffer contains Transferables, free them. Note that custom
|
||||
// Transferables will use the JSStructuredCloneCallbacks::freeTransfer() to
|
||||
// delete their transferables.
|
||||
void
|
||||
JSStructuredCloneData::discardTransferables()
|
||||
{
|
||||
if (!Size())
|
||||
return;
|
||||
if (ownTransferables_ == OwnTransferablePolicy::OwnsTransferablesIfAny)
|
||||
DiscardTransferables(bufList_, callbacks_, closure_);
|
||||
|
||||
if (ownTransferables_ != OwnTransferablePolicy::OwnsTransferablesIfAny)
|
||||
return;
|
||||
|
||||
// DifferentProcess clones cannot contain pointers, so nothing needs to be
|
||||
// released.
|
||||
if (scope_ == JS::StructuredCloneScope::DifferentProcess)
|
||||
return;
|
||||
|
||||
FreeTransferStructuredCloneOp freeTransfer = nullptr;
|
||||
if (callbacks_)
|
||||
freeTransfer = callbacks_->freeTransfer;
|
||||
|
||||
auto point = BufferIterator<uint64_t, SystemAllocPolicy>(*this);
|
||||
if (point.done())
|
||||
return; // Empty buffer
|
||||
|
||||
uint32_t tag, data;
|
||||
MOZ_RELEASE_ASSERT(point.canPeek());
|
||||
SCInput::getPair(point.peek(), &tag, &data);
|
||||
point.next();
|
||||
|
||||
if (tag == SCTAG_HEADER) {
|
||||
if (point.done())
|
||||
return;
|
||||
|
||||
MOZ_RELEASE_ASSERT(point.canPeek());
|
||||
SCInput::getPair(point.peek(), &tag, &data);
|
||||
point.next();
|
||||
}
|
||||
|
||||
if (tag != SCTAG_TRANSFER_MAP_HEADER)
|
||||
return;
|
||||
|
||||
if (TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED)
|
||||
return;
|
||||
|
||||
// freeTransfer should not GC
|
||||
JS::AutoSuppressGCAnalysis nogc;
|
||||
|
||||
if (point.done())
|
||||
return;
|
||||
|
||||
uint64_t numTransferables = NativeEndian::swapFromLittleEndian(point.peek());
|
||||
point.next();
|
||||
while (numTransferables--) {
|
||||
if (!point.canPeek())
|
||||
return;
|
||||
|
||||
uint32_t ownership;
|
||||
SCInput::getPair(point.peek(), &tag, &ownership);
|
||||
point.next();
|
||||
MOZ_ASSERT(tag >= SCTAG_TRANSFER_MAP_PENDING_ENTRY);
|
||||
if (!point.canPeek())
|
||||
return;
|
||||
|
||||
void* content;
|
||||
SCInput::getPtr(point.peek(), &content);
|
||||
point.next();
|
||||
if (!point.canPeek())
|
||||
return;
|
||||
|
||||
uint64_t extraData = NativeEndian::swapFromLittleEndian(point.peek());
|
||||
point.next();
|
||||
|
||||
if (ownership < JS::SCTAG_TMO_FIRST_OWNED)
|
||||
continue;
|
||||
|
||||
if (ownership == JS::SCTAG_TMO_ALLOC_DATA) {
|
||||
js_free(content);
|
||||
} else if (ownership == JS::SCTAG_TMO_MAPPED_DATA) {
|
||||
JS_ReleaseMappedArrayBufferContents(content, extraData);
|
||||
} else if (freeTransfer) {
|
||||
freeTransfer(tag, JS::TransferableOwnership(ownership), content, extraData, closure_);
|
||||
} else {
|
||||
MOZ_ASSERT(false, "unknown ownership");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(JSString::MAX_LENGTH < UINT32_MAX);
|
||||
@ -1260,7 +1260,7 @@ JSStructuredCloneWriter::writeSharedArrayBuffer(HandleObject obj)
|
||||
// cross-process. The cloneDataPolicy should have guarded against this;
|
||||
// since it did not then throw, with a very explicit message.
|
||||
|
||||
if (scope > JS::StructuredCloneScope::SameProcessDifferentThread) {
|
||||
if (output().scope() > JS::StructuredCloneScope::SameProcessDifferentThread) {
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_SHMEM_POLICY);
|
||||
return false;
|
||||
}
|
||||
@ -1605,7 +1605,7 @@ JSStructuredCloneWriter::startWrite(HandleValue v)
|
||||
bool
|
||||
JSStructuredCloneWriter::writeHeader()
|
||||
{
|
||||
return out.writePair(SCTAG_HEADER, (uint32_t)scope);
|
||||
return out.writePair(SCTAG_HEADER, (uint32_t)output().scope());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1663,6 +1663,7 @@ JSStructuredCloneWriter::transferOwnership()
|
||||
|
||||
JSContext* cx = context();
|
||||
RootedObject obj(cx);
|
||||
JS::StructuredCloneScope scope = output().scope();
|
||||
for (auto tr = transferableObjects.all(); !tr.empty(); tr.popFront()) {
|
||||
obj = tr.front();
|
||||
|
||||
@ -2809,7 +2810,7 @@ JS_StructuredClone(JSContext* cx, HandleValue value, MutableHandleValue vp,
|
||||
}
|
||||
|
||||
JSAutoStructuredCloneBuffer::JSAutoStructuredCloneBuffer(JSAutoStructuredCloneBuffer&& other)
|
||||
: scope_(other.scope_)
|
||||
: scope_(other.scope()), data_(other.scope())
|
||||
{
|
||||
data_.ownTransferables_ = other.data_.ownTransferables_;
|
||||
other.steal(&data_, &version_, &data_.callbacks_, &data_.closure_);
|
||||
@ -2975,5 +2976,5 @@ JS_ObjectNotWritten(JSStructuredCloneWriter* w, HandleObject obj)
|
||||
JS_PUBLIC_API(JS::StructuredCloneScope)
|
||||
JS_GetStructuredCloneScope(JSStructuredCloneWriter* w)
|
||||
{
|
||||
return w->cloneScope();
|
||||
return w->output().scope();
|
||||
}
|
||||
|
@ -140,13 +140,3 @@ nsColorControlFrame::GetContentInsertionFrame()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsColorControlFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
if (aType == CSSPseudoElementType::mozColorSwatch) {
|
||||
return mColorContent;
|
||||
}
|
||||
|
||||
return nsContainerFrame::GetPseudoElement(aType);
|
||||
}
|
||||
|
@ -47,8 +47,6 @@ public:
|
||||
int32_t aModType) override;
|
||||
virtual nsContainerFrame* GetContentInsertionFrame() override;
|
||||
|
||||
virtual Element* GetPseudoElement(CSSPseudoElementType aType) override;
|
||||
|
||||
// Refresh the color swatch, using associated input's value
|
||||
nsresult UpdateColor();
|
||||
|
||||
|
@ -271,13 +271,3 @@ nsMeterFrame::ShouldUseNativeStyle() const
|
||||
!PresContext()->HasAuthorSpecifiedRules(barFrame,
|
||||
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
|
||||
}
|
||||
|
||||
Element*
|
||||
nsMeterFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
if (aType == CSSPseudoElementType::mozMeterBar) {
|
||||
return mBarDiv;
|
||||
}
|
||||
|
||||
return nsContainerFrame::GetPseudoElement(aType);
|
||||
}
|
||||
|
@ -72,8 +72,6 @@ public:
|
||||
*/
|
||||
bool ShouldUseNativeStyle() const;
|
||||
|
||||
virtual Element* GetPseudoElement(mozilla::CSSPseudoElementType aType) override;
|
||||
|
||||
protected:
|
||||
// Helper function which reflow the anonymous div frame.
|
||||
void ReflowBarFrame(nsIFrame* aBarFrame,
|
||||
|
@ -743,35 +743,6 @@ nsNumberControlFrame::AnonTextControlIsEmpty()
|
||||
return value.IsEmpty();
|
||||
}
|
||||
|
||||
Element*
|
||||
nsNumberControlFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
if (aType == CSSPseudoElementType::mozNumberWrapper) {
|
||||
return mOuterWrapper;
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::mozNumberText) {
|
||||
return mTextField;
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::mozNumberSpinBox) {
|
||||
// Might be null.
|
||||
return mSpinBox;
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::mozNumberSpinUp) {
|
||||
// Might be null.
|
||||
return mSpinUp;
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::mozNumberSpinDown) {
|
||||
// Might be null.
|
||||
return mSpinDown;
|
||||
}
|
||||
|
||||
return nsContainerFrame::GetPseudoElement(aType);
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
a11y::AccType
|
||||
nsNumberControlFrame::AccessibleType()
|
||||
|
@ -157,8 +157,6 @@ public:
|
||||
*/
|
||||
void HandleSelectCall();
|
||||
|
||||
virtual Element* GetPseudoElement(CSSPseudoElementType aType) override;
|
||||
|
||||
bool ShouldUseNativeStyleForSpinner() const;
|
||||
|
||||
private:
|
||||
|
@ -284,13 +284,3 @@ nsProgressFrame::ShouldUseNativeStyle() const
|
||||
!PresContext()->HasAuthorSpecifiedRules(barFrame,
|
||||
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
|
||||
}
|
||||
|
||||
Element*
|
||||
nsProgressFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
if (aType == CSSPseudoElementType::mozProgressBar) {
|
||||
return mBarDiv;
|
||||
}
|
||||
|
||||
return nsContainerFrame::GetPseudoElement(aType);
|
||||
}
|
||||
|
@ -79,8 +79,6 @@ public:
|
||||
*/
|
||||
bool ShouldUseNativeStyle() const;
|
||||
|
||||
virtual Element* GetPseudoElement(CSSPseudoElementType aType) override;
|
||||
|
||||
protected:
|
||||
// Helper function to reflow a child frame.
|
||||
void ReflowChildFrame(nsIFrame* aChild,
|
||||
|
@ -888,24 +888,6 @@ nsRangeFrame::ShouldUseNativeStyle() const
|
||||
STYLES_DISABLING_NATIVE_THEMING);
|
||||
}
|
||||
|
||||
Element*
|
||||
nsRangeFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
if (aType == CSSPseudoElementType::mozRangeTrack) {
|
||||
return mTrackDiv;
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::mozRangeThumb) {
|
||||
return mThumbDiv;
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::mozRangeProgress) {
|
||||
return mProgressDiv;
|
||||
}
|
||||
|
||||
return nsContainerFrame::GetPseudoElement(aType);
|
||||
}
|
||||
|
||||
ComputedStyle*
|
||||
nsRangeFrame::GetAdditionalComputedStyle(int32_t aIndex) const
|
||||
{
|
||||
|
@ -149,8 +149,6 @@ public:
|
||||
*/
|
||||
void UpdateForValueChange();
|
||||
|
||||
virtual Element* GetPseudoElement(CSSPseudoElementType aType) override;
|
||||
|
||||
private:
|
||||
|
||||
nsresult MakeAnonymousDiv(Element** aResult,
|
||||
|
@ -1417,16 +1417,6 @@ nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::dom::Element*
|
||||
nsTextControlFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
if (aType == CSSPseudoElementType::placeholder) {
|
||||
return mPlaceholderDiv;
|
||||
}
|
||||
|
||||
return nsContainerFrame::GetPseudoElement(aType);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextControlFrame::EditorInitializer::Run()
|
||||
{
|
||||
|
@ -129,9 +129,6 @@ public:
|
||||
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) override;
|
||||
|
||||
virtual mozilla::dom::Element*
|
||||
GetPseudoElement(mozilla::CSSPseudoElementType aType) override;
|
||||
|
||||
//==== BEGIN NSIFORMCONTROLFRAME
|
||||
virtual void SetFocus(bool aOn , bool aRepaint) override;
|
||||
virtual nsresult SetFormProperty(nsAtom* aName, const nsAString& aValue) override;
|
||||
|
@ -11017,24 +11017,6 @@ nsIFrame::IsStackingContext()
|
||||
return IsStackingContext(disp, StylePosition(), isPositioned, isVisuallyAtomic);
|
||||
}
|
||||
|
||||
Element*
|
||||
nsIFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
if (!mContent) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::before) {
|
||||
return nsLayoutUtils::GetBeforePseudo(mContent);
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::after) {
|
||||
return nsLayoutUtils::GetAfterPseudo(mContent);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsFrameScrolledOutOfView(nsIFrame* aTarget,
|
||||
const nsRect& aTargetRect,
|
||||
|
@ -4005,14 +4005,6 @@ public:
|
||||
return !HasAllStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content node within the anonymous content that this frame
|
||||
* generated and which corresponds to the specified pseudo-element type,
|
||||
* or nullptr if there is no such anonymous content.
|
||||
*/
|
||||
virtual mozilla::dom::Element*
|
||||
GetPseudoElement(mozilla::CSSPseudoElementType aType);
|
||||
|
||||
/*
|
||||
* @param aStyleDisplay: If the caller has this->StyleDisplay(), providing
|
||||
* it here will improve performance.
|
||||
|
@ -1 +1 @@
|
||||
6e4b0141df2f
|
||||
c8ee333b84a0
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "certutil.h"
|
||||
|
||||
#define MIN_KEY_BITS 512
|
||||
/* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */
|
||||
/* MAX_KEY_BITS should agree with RSA_MAX_MODULUS_BITS in freebl */
|
||||
#define MAX_KEY_BITS 8192
|
||||
#define DEFAULT_KEY_BITS 2048
|
||||
|
||||
|
@ -10,4 +10,3 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <memory>
|
||||
#include "cert.h"
|
||||
#include "keyhi.h"
|
||||
#include "p12.h"
|
||||
#include "pk11pub.h"
|
||||
#include "pkcs11uri.h"
|
||||
#include "sslexp.h"
|
||||
@ -41,6 +42,9 @@ struct ScopedDelete {
|
||||
void operator()(SSLResumptionTokenInfo* token) {
|
||||
SSL_DestroyResumptionTokenInfo(token);
|
||||
}
|
||||
void operator()(SEC_PKCS12DecoderContext* dcx) {
|
||||
SEC_PKCS12DecoderFinish(dcx);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@ -73,6 +77,7 @@ SCOPED(PLArenaPool);
|
||||
SCOPED(PK11Context);
|
||||
SCOPED(PK11GenericObject);
|
||||
SCOPED(SSLResumptionTokenInfo);
|
||||
SCOPED(SEC_PKCS12DecoderContext);
|
||||
|
||||
#undef SCOPED
|
||||
|
||||
|
@ -87,15 +87,12 @@ static void SetupCallbacks(PRFileDesc* fd, ClientConfig* config) {
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
|
||||
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
|
||||
std::unique_ptr<NSSDatabase> db(new NSSDatabase());
|
||||
assert(db != nullptr);
|
||||
|
||||
EnableAllProtocolVersions();
|
||||
std::unique_ptr<ClientConfig> config(new ClientConfig(data, len));
|
||||
|
||||
// Clear the cache. We never want to resume as we couldn't reproduce that.
|
||||
SSL_ClearSessionCache();
|
||||
|
||||
// Reset the RNG state.
|
||||
assert(RNG_RandomUpdate(NULL, 0) == SECSuccess);
|
||||
|
||||
@ -114,6 +111,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
|
||||
SetupCallbacks(ssl_fd, config.get());
|
||||
DoHandshake(ssl_fd, false);
|
||||
|
||||
// Release all SIDs.
|
||||
SSL_ClearSessionCache();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
'sources': [
|
||||
'der_getint_unittest.cc',
|
||||
'der_quickder_unittest.cc',
|
||||
'p12_import_unittest.cc',
|
||||
'<(DEPTH)/gtests/common/gtests.cc'
|
||||
],
|
||||
'dependencies': [
|
||||
@ -21,6 +22,8 @@
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss3',
|
||||
'<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
|
||||
'<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@ -9,6 +9,7 @@ MODULE = nss
|
||||
CPPSRCS = \
|
||||
der_getint_unittest.cc \
|
||||
der_quickder_unittest.cc \
|
||||
p12_import_unittest.cc \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
|
||||
|
251
security/nss/gtests/der_gtest/p12_import_unittest.cc
Normal file
251
security/nss/gtests/der_gtest/p12_import_unittest.cc
Normal file
@ -0,0 +1,251 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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 "nss.h"
|
||||
#include "p12.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "scoped_ptrs.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
static const uint8_t cert_p12[] = {
|
||||
0x30, 0x82, 0x0a, 0x1f, 0x02, 0x01, 0x03, 0x30, 0x82, 0x09, 0xe5, 0x06,
|
||||
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
|
||||
0x09, 0xd6, 0x04, 0x82, 0x09, 0xd2, 0x30, 0x82, 0x09, 0xce, 0x30, 0x82,
|
||||
0x04, 0x42, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
|
||||
0x06, 0xa0, 0x82, 0x04, 0x33, 0x30, 0x82, 0x04, 0x2f, 0x02, 0x01, 0x00,
|
||||
0x30, 0x82, 0x04, 0x28, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||
0x01, 0x07, 0x01, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||
0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86,
|
||||
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, 0x05,
|
||||
0x66, 0xc7, 0x5c, 0x27, 0x4e, 0x15, 0xd9, 0x02, 0x02, 0x08, 0x00, 0x30,
|
||||
0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, 0x05,
|
||||
0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
|
||||
0x01, 0x2a, 0x04, 0x10, 0x4e, 0x61, 0xa7, 0x23, 0xc4, 0x3b, 0x37, 0xea,
|
||||
0xba, 0xe9, 0x9f, 0x44, 0x8e, 0x5e, 0xf7, 0xf2, 0x80, 0x82, 0x03, 0xc0,
|
||||
0x76, 0x7d, 0x91, 0x89, 0xe1, 0x04, 0x59, 0x91, 0x0c, 0x72, 0x14, 0x93,
|
||||
0xc4, 0x37, 0xe8, 0xd1, 0xbb, 0x49, 0xfc, 0x23, 0x49, 0x19, 0x6f, 0xc9,
|
||||
0x05, 0x08, 0x52, 0xd8, 0x63, 0xdf, 0x27, 0x63, 0x24, 0x85, 0x73, 0x11,
|
||||
0xfa, 0x6d, 0xca, 0xed, 0xb2, 0x91, 0x77, 0xc6, 0x1f, 0x0b, 0xdb, 0x4d,
|
||||
0x66, 0x34, 0xb9, 0x51, 0xef, 0xf0, 0x8f, 0xf8, 0x71, 0x2b, 0x68, 0xf7,
|
||||
0x5c, 0xdf, 0x99, 0x21, 0x7c, 0xb6, 0xa7, 0x45, 0xdb, 0x71, 0x69, 0x0b,
|
||||
0xb3, 0x2e, 0xff, 0x84, 0xcd, 0xd1, 0xb8, 0x87, 0xe9, 0xaa, 0x3e, 0xcd,
|
||||
0x11, 0x90, 0xcb, 0xd8, 0xe7, 0x08, 0x87, 0x32, 0x82, 0x26, 0x69, 0x9b,
|
||||
0xa6, 0xb1, 0x76, 0xf2, 0x28, 0xe2, 0x6c, 0xf5, 0x50, 0x16, 0x2d, 0x13,
|
||||
0x75, 0x73, 0xed, 0xd1, 0x40, 0x1b, 0xd9, 0x43, 0xf5, 0x1d, 0x60, 0x98,
|
||||
0x33, 0x5e, 0x18, 0xb0, 0xba, 0xe0, 0x8a, 0xaa, 0xa4, 0x3b, 0x78, 0x49,
|
||||
0x59, 0x5f, 0xa4, 0xd5, 0xb5, 0x10, 0xb8, 0x87, 0x46, 0x48, 0xff, 0x5e,
|
||||
0x91, 0x3b, 0xf9, 0xef, 0x29, 0x92, 0x99, 0xfd, 0x22, 0x8c, 0xcd, 0x05,
|
||||
0x2e, 0x0a, 0x24, 0xbf, 0xe4, 0x1b, 0x95, 0x86, 0x94, 0xf2, 0xd9, 0x8c,
|
||||
0x4d, 0xac, 0xe8, 0xb8, 0x49, 0x93, 0x74, 0xcd, 0x79, 0x3f, 0xa4, 0x29,
|
||||
0x09, 0x5a, 0x00, 0x44, 0xfe, 0x75, 0x53, 0x23, 0x7e, 0xe4, 0xf5, 0x71,
|
||||
0xcf, 0x1e, 0x48, 0x1d, 0x89, 0x42, 0x67, 0xa6, 0x1d, 0x0d, 0x0b, 0xe0,
|
||||
0x4a, 0x7a, 0x59, 0xe0, 0x88, 0x63, 0xfc, 0x72, 0x97, 0xc2, 0x9f, 0x5d,
|
||||
0xc3, 0xb2, 0x75, 0x73, 0x25, 0x10, 0x6f, 0x40, 0x93, 0x4f, 0x7d, 0x69,
|
||||
0x01, 0x2d, 0xf4, 0xbe, 0xa9, 0xd9, 0x3c, 0x83, 0x77, 0x92, 0xf4, 0xa1,
|
||||
0x2a, 0x7d, 0x3e, 0xab, 0x2d, 0xa1, 0x53, 0x63, 0x98, 0xaf, 0xc6, 0x11,
|
||||
0x78, 0x3d, 0x37, 0xa9, 0x3f, 0x9c, 0xa8, 0xce, 0xc1, 0x9f, 0xac, 0x45,
|
||||
0x9a, 0x2e, 0x38, 0x9f, 0x08, 0xf9, 0x2d, 0x9e, 0xf5, 0xca, 0x4d, 0x33,
|
||||
0x77, 0x89, 0x2b, 0xde, 0x32, 0x05, 0xe4, 0x39, 0x1a, 0x78, 0x06, 0x7f,
|
||||
0x74, 0x28, 0xab, 0x07, 0xbc, 0x59, 0xd0, 0x52, 0x11, 0x1b, 0x6a, 0x98,
|
||||
0x51, 0xed, 0x5c, 0xf7, 0x96, 0x59, 0xad, 0xb1, 0x48, 0x81, 0xc8, 0xde,
|
||||
0xec, 0xb0, 0x16, 0x7d, 0x61, 0x09, 0xaf, 0x36, 0xe8, 0x2d, 0xd3, 0x88,
|
||||
0x99, 0x35, 0xf2, 0x72, 0xa5, 0xfd, 0xd9, 0xbe, 0xf5, 0x6d, 0x52, 0x4f,
|
||||
0xdb, 0x65, 0x1b, 0x06, 0xfd, 0x1f, 0x61, 0xb3, 0xae, 0x03, 0x96, 0x50,
|
||||
0x96, 0xc4, 0x74, 0x28, 0x26, 0xda, 0x51, 0xc2, 0xd4, 0xff, 0xce, 0xc5,
|
||||
0x26, 0xea, 0x8c, 0xfd, 0x1e, 0x22, 0x03, 0xf0, 0xcd, 0x00, 0xf2, 0x72,
|
||||
0xf3, 0x81, 0x46, 0x1e, 0x95, 0xaf, 0xe1, 0xc1, 0x0a, 0x12, 0xfe, 0xb0,
|
||||
0x97, 0x2d, 0x40, 0xe8, 0x6d, 0xde, 0xe0, 0x9c, 0x7f, 0xad, 0x85, 0x89,
|
||||
0x28, 0x88, 0x4a, 0x64, 0xc1, 0xa4, 0x2f, 0xb6, 0x25, 0xae, 0x89, 0xb4,
|
||||
0xab, 0x02, 0xea, 0xca, 0xd6, 0x05, 0x4f, 0x3a, 0x64, 0xd0, 0xbf, 0x2d,
|
||||
0xba, 0x0a, 0x9c, 0x5a, 0xa5, 0x0b, 0xf5, 0xc7, 0x84, 0x6e, 0xb4, 0x5c,
|
||||
0x0e, 0x43, 0x96, 0xac, 0xfe, 0xc1, 0xc5, 0x3d, 0x15, 0x2b, 0x4d, 0x67,
|
||||
0x2a, 0x09, 0xd8, 0x64, 0x83, 0x13, 0x00, 0x10, 0xe1, 0x60, 0x76, 0x9b,
|
||||
0xf0, 0xa0, 0xdc, 0x8c, 0x4b, 0x4f, 0xc5, 0x93, 0xa8, 0xf8, 0xef, 0xd9,
|
||||
0x75, 0xdc, 0x62, 0xe9, 0xcf, 0xdf, 0x3f, 0x7b, 0x8d, 0x2c, 0x0e, 0x5a,
|
||||
0x99, 0xc6, 0x38, 0x4c, 0xd9, 0xfb, 0xe6, 0xb5, 0x1b, 0x6e, 0xbd, 0xae,
|
||||
0xef, 0x89, 0x71, 0x4e, 0xfd, 0x74, 0x46, 0x35, 0xf9, 0x48, 0x43, 0x11,
|
||||
0x81, 0xcd, 0x6f, 0xdc, 0xf3, 0x2e, 0x92, 0x93, 0x9e, 0xca, 0xf8, 0xfa,
|
||||
0xc6, 0x56, 0x75, 0x1e, 0x04, 0x89, 0x7d, 0x1c, 0x2e, 0xdb, 0xbd, 0x5b,
|
||||
0xec, 0xc8, 0x2d, 0xa3, 0xe2, 0x05, 0xef, 0xe9, 0x5f, 0x05, 0x4b, 0x89,
|
||||
0x82, 0x0c, 0x1e, 0x8c, 0x74, 0xe1, 0x5a, 0x67, 0xe4, 0x97, 0x9b, 0x22,
|
||||
0xd7, 0xdc, 0xe2, 0x74, 0xcf, 0x93, 0xc1, 0xca, 0xc6, 0xde, 0xae, 0xc0,
|
||||
0xd2, 0xf9, 0x57, 0xc5, 0x90, 0x96, 0x48, 0x0a, 0x25, 0x43, 0x75, 0xc1,
|
||||
0x94, 0xa4, 0xd5, 0x14, 0xb2, 0x27, 0xf8, 0x45, 0xf1, 0x3c, 0x01, 0xd6,
|
||||
0xb8, 0x73, 0x1c, 0xb6, 0x55, 0xc5, 0xc9, 0x10, 0x28, 0x2f, 0xba, 0x18,
|
||||
0x36, 0x8d, 0xfe, 0x0b, 0x23, 0xf3, 0x9a, 0x98, 0xfb, 0x2f, 0x59, 0x52,
|
||||
0x3a, 0x0f, 0x75, 0x60, 0xa0, 0x92, 0x0d, 0x78, 0xf0, 0xc7, 0x5d, 0x9d,
|
||||
0x3a, 0x72, 0xd0, 0xd1, 0x30, 0x73, 0x9e, 0x3c, 0x03, 0x99, 0x4c, 0xe2,
|
||||
0xe5, 0xd4, 0x77, 0xfe, 0x3a, 0x92, 0x08, 0x5b, 0x99, 0x51, 0x15, 0x57,
|
||||
0x05, 0x13, 0x51, 0xc2, 0xf4, 0xb5, 0x2d, 0xae, 0x68, 0x9f, 0x4e, 0xbf,
|
||||
0x00, 0x11, 0xc1, 0xe1, 0x48, 0xb3, 0xce, 0x36, 0x42, 0x6a, 0x74, 0xd7,
|
||||
0xe7, 0x84, 0x1e, 0xf3, 0x47, 0xc4, 0xab, 0x59, 0x18, 0x15, 0x31, 0xa4,
|
||||
0x28, 0x68, 0x16, 0xa3, 0x68, 0xbf, 0x6c, 0xfe, 0x7a, 0x36, 0xd9, 0xc1,
|
||||
0x22, 0xd6, 0x5e, 0x2d, 0xbb, 0x9a, 0x1f, 0xb6, 0x8c, 0xa6, 0x65, 0x24,
|
||||
0x3e, 0x01, 0x9c, 0x75, 0x5e, 0x17, 0x42, 0x12, 0x89, 0x85, 0x6f, 0x05,
|
||||
0xac, 0x54, 0xd5, 0x02, 0xea, 0x1e, 0xc2, 0xe1, 0xcd, 0x61, 0x0e, 0x53,
|
||||
0xd5, 0x9d, 0x3a, 0x67, 0x1b, 0x50, 0x9b, 0x90, 0x18, 0x66, 0x6d, 0xb2,
|
||||
0x7f, 0x3a, 0x69, 0xc9, 0xef, 0x07, 0x17, 0x91, 0x8a, 0xe9, 0x15, 0x35,
|
||||
0xed, 0x70, 0x9e, 0x74, 0x8c, 0xe7, 0xf4, 0xaa, 0xcf, 0xbe, 0xa3, 0x98,
|
||||
0x89, 0x8d, 0x3c, 0x5e, 0xa4, 0x6b, 0x8f, 0x1b, 0x18, 0x04, 0x79, 0xd2,
|
||||
0x11, 0x64, 0xb1, 0xc7, 0x68, 0xca, 0xaf, 0x44, 0xa1, 0x39, 0x29, 0x58,
|
||||
0x70, 0x4e, 0xce, 0xb7, 0x7a, 0x3c, 0x4b, 0xdc, 0x32, 0x92, 0x76, 0x74,
|
||||
0xab, 0x0a, 0x6f, 0x8b, 0x74, 0xf5, 0xfd, 0xed, 0x3b, 0x11, 0x95, 0xe8,
|
||||
0x10, 0x74, 0x4c, 0xd8, 0xbe, 0x0f, 0x50, 0xee, 0xa0, 0xee, 0x39, 0xd8,
|
||||
0x9f, 0xa1, 0xa0, 0x21, 0xa3, 0x47, 0x8c, 0xa6, 0xd9, 0xca, 0x8c, 0xb3,
|
||||
0x8b, 0x86, 0x9e, 0x31, 0x3b, 0xcc, 0x7f, 0xea, 0x23, 0xb1, 0x25, 0x73,
|
||||
0xfb, 0x66, 0x99, 0x28, 0xff, 0xf4, 0xe9, 0xb7, 0x19, 0x3e, 0xd5, 0xc6,
|
||||
0x5d, 0xd1, 0xaa, 0x08, 0x6f, 0xf2, 0xff, 0xab, 0x39, 0x69, 0x1f, 0xd3,
|
||||
0x6b, 0x20, 0xf3, 0x2f, 0xe4, 0xd5, 0xb8, 0x76, 0x3f, 0x6c, 0x8f, 0x05,
|
||||
0x3c, 0xe0, 0x18, 0x81, 0x82, 0xca, 0x05, 0x7f, 0xc0, 0x8e, 0x87, 0x50,
|
||||
0xfb, 0xb1, 0x65, 0xfa, 0x2f, 0xb7, 0xba, 0x20, 0x0b, 0x35, 0x5c, 0x87,
|
||||
0xba, 0x90, 0x5a, 0x7f, 0xfc, 0xe9, 0xf2, 0x98, 0x5f, 0x6e, 0xb2, 0xcc,
|
||||
0xef, 0x4b, 0x2d, 0xde, 0xdd, 0x6f, 0xd9, 0x8e, 0x79, 0x89, 0x45, 0xcd,
|
||||
0x4c, 0xdf, 0x27, 0xf1, 0x26, 0x47, 0x9e, 0x83, 0xdb, 0x73, 0x4a, 0x20,
|
||||
0x84, 0xde, 0x09, 0xe0, 0x58, 0xfe, 0x19, 0xcb, 0x92, 0xc4, 0x5b, 0x83,
|
||||
0x30, 0x82, 0x05, 0x84, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||
0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0x75, 0x04, 0x82, 0x05, 0x71, 0x30,
|
||||
0x82, 0x05, 0x6d, 0x30, 0x82, 0x05, 0x69, 0x06, 0x0b, 0x2a, 0x86, 0x48,
|
||||
0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x82, 0x05, 0x31,
|
||||
0x30, 0x82, 0x05, 0x2d, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||||
0xf7, 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a,
|
||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08,
|
||||
0x5c, 0x72, 0x5e, 0xfb, 0xbc, 0x49, 0xaa, 0xa1, 0x02, 0x02, 0x08, 0x00,
|
||||
0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09,
|
||||
0x05, 0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x01, 0x2a, 0x04, 0x10, 0xcb, 0xa8, 0xda, 0x75, 0xba, 0x64, 0x22,
|
||||
0x70, 0x39, 0x3c, 0x83, 0x35, 0x0b, 0x41, 0xc4, 0x49, 0x04, 0x82, 0x04,
|
||||
0xd0, 0xb3, 0x3d, 0x9b, 0x03, 0x34, 0xdf, 0x62, 0x37, 0xb0, 0xbb, 0x37,
|
||||
0x0d, 0x88, 0x8c, 0x6b, 0xf2, 0x46, 0x33, 0xa4, 0x4b, 0x48, 0x86, 0x0a,
|
||||
0x36, 0x37, 0x24, 0x21, 0x08, 0x8e, 0x86, 0xbf, 0x4e, 0x9c, 0xe7, 0xa9,
|
||||
0x56, 0x4a, 0x02, 0xb4, 0x74, 0x6a, 0x8a, 0x1e, 0x51, 0x91, 0xe3, 0x8f,
|
||||
0xe3, 0xf6, 0xca, 0x0a, 0x2d, 0xe7, 0x09, 0x5e, 0x1e, 0x59, 0x46, 0x01,
|
||||
0xda, 0xe9, 0x5b, 0xb9, 0xd8, 0x15, 0x7c, 0x05, 0xd9, 0x5f, 0x8c, 0x3d,
|
||||
0xd4, 0xb2, 0xff, 0x25, 0x9d, 0xfe, 0x0e, 0xe3, 0x0c, 0xf0, 0x7f, 0x30,
|
||||
0x25, 0x92, 0x0e, 0x44, 0xf4, 0x16, 0xc7, 0xa2, 0x22, 0xb2, 0x31, 0xfa,
|
||||
0x55, 0x97, 0xf7, 0xd0, 0xd7, 0x58, 0x1f, 0x96, 0x81, 0x06, 0x86, 0xbb,
|
||||
0x07, 0x30, 0x9d, 0x01, 0xb8, 0x15, 0xb2, 0x81, 0xa9, 0x35, 0x09, 0x2c,
|
||||
0x97, 0xbc, 0x8e, 0x2e, 0x2e, 0x30, 0x20, 0x51, 0x94, 0x9d, 0x9f, 0xbd,
|
||||
0x83, 0x48, 0x7b, 0x25, 0xfc, 0x95, 0x42, 0xd7, 0x29, 0xd5, 0x67, 0xcd,
|
||||
0x48, 0xc6, 0x78, 0xe1, 0x6d, 0xdf, 0xf8, 0x0b, 0x3a, 0x95, 0xcc, 0xd0,
|
||||
0x93, 0xfe, 0x23, 0x8d, 0x99, 0xd9, 0x8c, 0x67, 0x38, 0x9f, 0xd0, 0x4c,
|
||||
0xff, 0x32, 0x45, 0x32, 0xa9, 0xe8, 0x9d, 0xbc, 0xbf, 0xaa, 0xb2, 0x49,
|
||||
0xaa, 0x1d, 0xa0, 0x04, 0x53, 0x14, 0xa4, 0x77, 0x96, 0x3f, 0x17, 0xbb,
|
||||
0x2e, 0x14, 0xbe, 0x39, 0x6b, 0x69, 0x16, 0x7a, 0x99, 0xb2, 0xf4, 0x16,
|
||||
0x1a, 0xb7, 0xaa, 0x0a, 0x97, 0xd9, 0x1d, 0x62, 0xbe, 0xfc, 0x38, 0x00,
|
||||
0x6c, 0x65, 0x75, 0xe0, 0xb0, 0x65, 0x8f, 0xb6, 0x4b, 0xe7, 0x21, 0x41,
|
||||
0x65, 0x65, 0x5a, 0x7c, 0x5b, 0xe8, 0x70, 0x83, 0x71, 0xd6, 0x65, 0x7c,
|
||||
0x4f, 0x00, 0x90, 0x55, 0xca, 0xff, 0xc9, 0x3f, 0x61, 0x1e, 0xc0, 0x41,
|
||||
0x67, 0x0c, 0x71, 0xb2, 0xef, 0x12, 0x8e, 0xb1, 0xaa, 0xcf, 0xf1, 0x78,
|
||||
0x9f, 0x5b, 0xb9, 0x7b, 0xbe, 0x04, 0x39, 0xf0, 0x87, 0xca, 0x3a, 0x77,
|
||||
0x31, 0xab, 0x85, 0x8f, 0x4f, 0x06, 0xad, 0x45, 0xf2, 0xe2, 0xc2, 0x20,
|
||||
0x74, 0xf1, 0xdc, 0x21, 0x3f, 0x79, 0x0d, 0xcc, 0xcf, 0x7f, 0xb9, 0x85,
|
||||
0x9e, 0x1a, 0x1b, 0x84, 0xe2, 0x5b, 0xe3, 0x77, 0x27, 0x91, 0xcc, 0xf2,
|
||||
0xe4, 0xf2, 0x19, 0xdd, 0x98, 0x64, 0x9d, 0xcb, 0xf1, 0xc5, 0xe6, 0x7b,
|
||||
0x75, 0x55, 0x4e, 0xa5, 0xca, 0xe3, 0x5b, 0xbe, 0xc2, 0xcd, 0x83, 0x27,
|
||||
0x92, 0xe1, 0x23, 0x3f, 0xd7, 0x3d, 0xb7, 0x3a, 0x8b, 0x3a, 0x26, 0xc1,
|
||||
0xfb, 0xed, 0x69, 0x7a, 0xab, 0xec, 0x0a, 0xe5, 0xaa, 0x81, 0x9f, 0xdf,
|
||||
0x97, 0x45, 0x64, 0x35, 0x7d, 0xad, 0x88, 0x4a, 0x75, 0x13, 0xc3, 0x13,
|
||||
0xd6, 0x9a, 0xf3, 0xa2, 0x94, 0xf7, 0x96, 0x09, 0xa7, 0xbe, 0xb8, 0xe4,
|
||||
0x29, 0x7d, 0xb0, 0xef, 0x4a, 0x5d, 0x0d, 0x02, 0xb4, 0x10, 0x54, 0x17,
|
||||
0x62, 0xef, 0xe2, 0xad, 0x89, 0x6d, 0x91, 0x51, 0x7e, 0x35, 0x28, 0xb4,
|
||||
0xe7, 0x02, 0xbb, 0xcb, 0x03, 0x37, 0xa6, 0xeb, 0x55, 0x51, 0xc0, 0xc2,
|
||||
0x21, 0x7a, 0x78, 0x44, 0x44, 0x70, 0x06, 0xb0, 0x5d, 0x19, 0xaa, 0xcb,
|
||||
0xf1, 0x9f, 0xaa, 0xd3, 0x5a, 0x29, 0xc4, 0xc7, 0x7a, 0x36, 0x1d, 0x65,
|
||||
0x21, 0x52, 0xf9, 0xe2, 0xc7, 0x60, 0xd4, 0x32, 0x03, 0xdf, 0x03, 0xcc,
|
||||
0xe5, 0x7c, 0xf9, 0x15, 0xe3, 0xe6, 0x46, 0xeb, 0xa8, 0xa8, 0x6f, 0xe7,
|
||||
0x46, 0x03, 0xc7, 0x5c, 0x29, 0xf6, 0xac, 0x61, 0x2d, 0xbe, 0xa0, 0xda,
|
||||
0xdc, 0xca, 0x29, 0x35, 0x3b, 0xa0, 0x43, 0x22, 0x22, 0x61, 0x65, 0x8f,
|
||||
0x2d, 0x13, 0xce, 0x61, 0x7c, 0x27, 0x45, 0x9d, 0x9b, 0x8d, 0xd6, 0xc1,
|
||||
0xb5, 0x8c, 0x5b, 0xdb, 0xbb, 0xf6, 0x7e, 0x9a, 0xd4, 0x5c, 0x6b, 0x7e,
|
||||
0xf3, 0x6d, 0x7e, 0x45, 0x2e, 0x55, 0x7d, 0x9f, 0x62, 0xc7, 0xf4, 0x03,
|
||||
0x6f, 0xb9, 0x02, 0xcf, 0x3d, 0x07, 0xc5, 0xc8, 0xce, 0x9e, 0xac, 0x56,
|
||||
0x43, 0x8b, 0xcc, 0xf0, 0x2d, 0xc5, 0x56, 0xfa, 0x61, 0xf9, 0xee, 0x1b,
|
||||
0x89, 0xa9, 0xd6, 0xe8, 0x1e, 0xa2, 0xdf, 0xfd, 0x0d, 0x33, 0x03, 0x91,
|
||||
0xd9, 0x30, 0x4d, 0xfb, 0x2d, 0x7e, 0x5b, 0xb0, 0xb5, 0x55, 0x1e, 0x9c,
|
||||
0x13, 0x96, 0x5a, 0xa6, 0xab, 0x88, 0x79, 0xe7, 0x42, 0x31, 0xb2, 0x2d,
|
||||
0xf8, 0x40, 0x89, 0xe4, 0x96, 0x4c, 0x42, 0xc9, 0x72, 0xd1, 0x8f, 0x3f,
|
||||
0x2d, 0xee, 0x1d, 0x91, 0xe0, 0xfb, 0x1f, 0xb5, 0x94, 0x41, 0xce, 0x89,
|
||||
0xed, 0xe7, 0xec, 0xa0, 0xb6, 0xb2, 0xa2, 0x5c, 0x72, 0xa1, 0x91, 0x40,
|
||||
0x82, 0xde, 0x62, 0xba, 0x12, 0x12, 0xa1, 0xab, 0x31, 0x62, 0x38, 0x48,
|
||||
0x4c, 0x49, 0x9e, 0x6c, 0xf3, 0xf1, 0x69, 0x3e, 0x8b, 0x6a, 0x24, 0x45,
|
||||
0x99, 0x5c, 0x5a, 0xe3, 0x52, 0x24, 0xb7, 0xcf, 0xf0, 0xc8, 0x82, 0x5e,
|
||||
0x9e, 0x10, 0x29, 0xcf, 0xda, 0x01, 0xd0, 0xc0, 0x81, 0xfd, 0x56, 0x15,
|
||||
0x1c, 0x6b, 0xff, 0x78, 0x91, 0xaa, 0x47, 0x63, 0xb0, 0xe2, 0xbd, 0x67,
|
||||
0x0d, 0x24, 0xc5, 0xfd, 0x1a, 0x6a, 0x6a, 0x71, 0x9b, 0xca, 0xc4, 0xb3,
|
||||
0xc0, 0x07, 0x3d, 0xd7, 0x3b, 0xf4, 0xc0, 0xb7, 0xb5, 0xc4, 0x46, 0x85,
|
||||
0x3d, 0x22, 0x03, 0x1b, 0xcf, 0xe6, 0xce, 0x2f, 0xae, 0x41, 0xcf, 0x67,
|
||||
0x6b, 0xd3, 0x87, 0x3f, 0xca, 0x4c, 0xb7, 0x9f, 0x47, 0x36, 0xa5, 0xd7,
|
||||
0xd3, 0x70, 0xf7, 0xc4, 0x9f, 0x7d, 0xbd, 0xe4, 0xc6, 0xec, 0x7b, 0x03,
|
||||
0xca, 0xb0, 0x78, 0x06, 0xa3, 0xf1, 0xd0, 0x98, 0xdf, 0x1c, 0x60, 0x90,
|
||||
0x61, 0xcb, 0x7b, 0x68, 0xd2, 0x8e, 0x24, 0x76, 0x7b, 0xf6, 0x2f, 0xf3,
|
||||
0x7b, 0x96, 0x2d, 0x80, 0x6f, 0xae, 0xc5, 0x2b, 0xe9, 0xad, 0x78, 0x25,
|
||||
0x78, 0x4e, 0xd7, 0x81, 0xb7, 0x60, 0x20, 0x0c, 0x20, 0x46, 0xb4, 0x88,
|
||||
0xfe, 0x12, 0x0a, 0x8d, 0x7a, 0x9a, 0x0b, 0xdd, 0x6d, 0x37, 0xb3, 0xa5,
|
||||
0x99, 0x1d, 0xf2, 0xd4, 0xa6, 0x79, 0x1e, 0x89, 0x1a, 0xda, 0xe8, 0x83,
|
||||
0x24, 0xc9, 0xd9, 0x1f, 0x76, 0x82, 0xec, 0x64, 0x35, 0x6b, 0x9b, 0xfd,
|
||||
0x91, 0x31, 0x96, 0xf2, 0x8b, 0x4f, 0x30, 0xbb, 0xd9, 0xcd, 0xe0, 0x66,
|
||||
0x73, 0xfd, 0xd7, 0x05, 0x16, 0x7c, 0xed, 0x94, 0xc0, 0xa0, 0x73, 0x9e,
|
||||
0xe7, 0x85, 0xac, 0x0e, 0x20, 0xd1, 0x5e, 0x66, 0x7a, 0xef, 0x93, 0x20,
|
||||
0xd7, 0x3f, 0xb5, 0xbd, 0xb7, 0xb7, 0xcb, 0x64, 0xc8, 0xde, 0x2f, 0xd9,
|
||||
0x92, 0x5f, 0xa1, 0xb6, 0xbd, 0xd0, 0xe6, 0xb4, 0x55, 0xf4, 0xa1, 0xa8,
|
||||
0x51, 0x5e, 0x00, 0x6f, 0xaa, 0x09, 0xff, 0x56, 0xb4, 0xbc, 0xdf, 0xc1,
|
||||
0x20, 0x13, 0xc4, 0x3c, 0x48, 0xb1, 0x6d, 0xeb, 0x19, 0xb8, 0xbf, 0x4f,
|
||||
0x3d, 0x35, 0x96, 0x14, 0xc3, 0xc3, 0xef, 0x8e, 0x0b, 0x95, 0xbc, 0x78,
|
||||
0x47, 0x6a, 0x6c, 0x24, 0x10, 0xbd, 0x06, 0x13, 0x5c, 0x69, 0x7b, 0xb5,
|
||||
0x53, 0x43, 0xd1, 0x7a, 0x1d, 0x9a, 0x7f, 0x57, 0xcd, 0x81, 0xc5, 0x3f,
|
||||
0xde, 0x98, 0xb5, 0x73, 0x95, 0xd2, 0x10, 0xcf, 0x4f, 0x6a, 0xce, 0xac,
|
||||
0x35, 0x49, 0x4d, 0xf3, 0xbe, 0xbf, 0x38, 0xf2, 0xcf, 0x1b, 0x1c, 0x19,
|
||||
0x27, 0xa3, 0x3f, 0xd9, 0x35, 0xfe, 0xc2, 0xe5, 0x49, 0x16, 0x28, 0xd0,
|
||||
0x8e, 0xb9, 0x34, 0x6e, 0x8b, 0xa5, 0xe2, 0x9c, 0xbe, 0xad, 0xa1, 0x43,
|
||||
0x61, 0x2e, 0x48, 0x65, 0xb3, 0x20, 0xe7, 0x1d, 0x65, 0x00, 0x9d, 0x6e,
|
||||
0x71, 0xe7, 0x79, 0x44, 0xac, 0x0c, 0x38, 0x5a, 0x1d, 0x40, 0x06, 0x30,
|
||||
0xd0, 0xe8, 0xbe, 0x95, 0x16, 0xaf, 0xd8, 0x5f, 0x67, 0xd3, 0xb0, 0x6a,
|
||||
0xa3, 0x7c, 0xc1, 0x9b, 0x3f, 0xc7, 0xae, 0x27, 0xb1, 0xc1, 0xb5, 0xce,
|
||||
0xdf, 0xbb, 0xa4, 0x4f, 0xb4, 0x58, 0xa1, 0xb9, 0x7c, 0x9c, 0x5f, 0x26,
|
||||
0x4f, 0x13, 0xfa, 0x7c, 0x1a, 0xb7, 0x1b, 0x69, 0xd6, 0x0e, 0x1b, 0x92,
|
||||
0x31, 0x4b, 0xb4, 0x71, 0x12, 0xc8, 0xc4, 0xbd, 0x99, 0xe3, 0xc8, 0x9d,
|
||||
0x68, 0xb3, 0x38, 0x35, 0x3f, 0x16, 0xd8, 0xde, 0x01, 0x71, 0xf6, 0x66,
|
||||
0x77, 0xcb, 0xbd, 0xe2, 0x97, 0x10, 0x91, 0x41, 0x00, 0xa1, 0x0d, 0x9d,
|
||||
0x40, 0x0b, 0xfc, 0x25, 0xc8, 0x44, 0xc3, 0x78, 0xaa, 0x89, 0xd5, 0x59,
|
||||
0xe4, 0xa2, 0x9e, 0xd0, 0x85, 0xa2, 0xdd, 0x80, 0x3b, 0x35, 0x5a, 0x50,
|
||||
0x86, 0xcd, 0x72, 0xf4, 0x9d, 0x69, 0x0e, 0x2d, 0x97, 0x42, 0x09, 0x5e,
|
||||
0xa6, 0x86, 0xf7, 0x35, 0xcf, 0x9b, 0x42, 0xa7, 0x60, 0xa0, 0x71, 0x41,
|
||||
0x28, 0x35, 0x22, 0xd6, 0x55, 0xe1, 0xdb, 0xb3, 0x8e, 0x0d, 0x47, 0xb7,
|
||||
0xd6, 0x02, 0x0f, 0xb1, 0xdf, 0xb8, 0xfb, 0xd8, 0x20, 0xcf, 0x6a, 0x47,
|
||||
0x3f, 0x8a, 0x91, 0x08, 0x64, 0x08, 0xba, 0x19, 0x10, 0x1f, 0xcf, 0xe5,
|
||||
0x34, 0xf1, 0x32, 0x49, 0x3b, 0xaf, 0x18, 0x67, 0x96, 0x47, 0x7f, 0x21,
|
||||
0x8a, 0x37, 0x15, 0x5c, 0xc0, 0xe8, 0x7b, 0xd6, 0x08, 0x5b, 0x45, 0x10,
|
||||
0x1f, 0x1c, 0x7f, 0xce, 0x3b, 0x88, 0xe5, 0x0e, 0xd9, 0x00, 0xce, 0xe5,
|
||||
0x9b, 0x4b, 0x25, 0xc7, 0x11, 0x8a, 0x4f, 0x22, 0xa7, 0x31, 0x25, 0x30,
|
||||
0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15,
|
||||
0x31, 0x16, 0x04, 0x14, 0xad, 0x7f, 0xeb, 0xe6, 0xb2, 0x6c, 0xf4, 0xdc,
|
||||
0x9f, 0x4d, 0x52, 0x40, 0x07, 0x15, 0xd9, 0xe8, 0xbc, 0x0d, 0x4e, 0xd7,
|
||||
0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
|
||||
0x1a, 0x05, 0x00, 0x04, 0x14, 0xa4, 0xac, 0xdb, 0xa8, 0x4c, 0xe9, 0x7a,
|
||||
0x02, 0x9d, 0x07, 0x39, 0x21, 0xf0, 0x71, 0xae, 0x46, 0x5a, 0xd8, 0x13,
|
||||
0x51, 0x04, 0x08, 0xa1, 0x52, 0xdd, 0x64, 0x46, 0xe9, 0x9e, 0x3e, 0x02,
|
||||
0x02, 0x08, 0x00};
|
||||
|
||||
class PK12ImportTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(PK12ImportTest, ImportPK12With2P7) {
|
||||
SECItem password = {siBuffer, nullptr, 0};
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
ScopedSEC_PKCS12DecoderContext dcx(
|
||||
SEC_PKCS12DecoderStart(&password, slot.get(), nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr));
|
||||
ASSERT_TRUE(dcx);
|
||||
SECStatus rv = SEC_PKCS12DecoderUpdate(
|
||||
dcx.get(), const_cast<uint8_t *>(cert_p12), sizeof(cert_p12));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = SEC_PKCS12DecoderVerify(dcx.get());
|
||||
// NSS can't properly decode this P12. But it shouldn't crash.
|
||||
ASSERT_EQ(SECFailure, rv);
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
209
security/nss/gtests/ssl_gtest/rsa8193.h
Normal file
209
security/nss/gtests/ssl_gtest/rsa8193.h
Normal file
@ -0,0 +1,209 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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/. */
|
||||
|
||||
// openssl req -nodes -x509 -newkey rsa:8193 -out cert.pem -days 365
|
||||
static const uint8_t rsa8193[] = {
|
||||
0x30, 0x82, 0x09, 0x61, 0x30, 0x82, 0x05, 0x48, 0xa0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x09, 0x00, 0xaf, 0xff, 0x37, 0x91, 0x3e, 0x44, 0xae, 0x57,
|
||||
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
|
||||
0x0b, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
|
||||
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
|
||||
0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
|
||||
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
|
||||
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
|
||||
0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x31, 0x37,
|
||||
0x30, 0x39, 0x34, 0x32, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30,
|
||||
0x35, 0x31, 0x37, 0x30, 0x39, 0x34, 0x32, 0x32, 0x39, 0x5a, 0x30, 0x45,
|
||||
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41,
|
||||
0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
|
||||
0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21,
|
||||
0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74,
|
||||
0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x82, 0x04,
|
||||
0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x04, 0x0f, 0x00, 0x30, 0x82, 0x04,
|
||||
0x0a, 0x02, 0x82, 0x04, 0x01, 0x01, 0x77, 0xd6, 0xa9, 0x93, 0x4e, 0x15,
|
||||
0xb5, 0x67, 0x70, 0x8e, 0xc3, 0x77, 0x4f, 0xc9, 0x8a, 0x06, 0xd9, 0xb9,
|
||||
0xa6, 0x41, 0xb8, 0xfa, 0x4a, 0x13, 0x26, 0xdc, 0x2b, 0xc5, 0x82, 0xa0,
|
||||
0x74, 0x8c, 0x1e, 0xe9, 0xc0, 0x70, 0x15, 0x56, 0xec, 0x1f, 0x7e, 0x91,
|
||||
0x6e, 0x31, 0x42, 0x8b, 0xd5, 0xe2, 0x0e, 0x9c, 0xeb, 0xff, 0xbc, 0xf9,
|
||||
0x42, 0xd3, 0xb9, 0x1c, 0x5e, 0x46, 0x80, 0x90, 0x5f, 0xe1, 0x59, 0x22,
|
||||
0x13, 0x71, 0xd3, 0xd6, 0x66, 0x7a, 0xe0, 0x56, 0x04, 0x10, 0x59, 0x01,
|
||||
0xb3, 0xb6, 0xd2, 0xc7, 0xa7, 0x3b, 0xbc, 0xe6, 0x38, 0x44, 0xd5, 0x71,
|
||||
0x66, 0x1d, 0xb2, 0x63, 0x2f, 0xa9, 0x5e, 0x80, 0x92, 0x3c, 0x21, 0x0e,
|
||||
0xe1, 0xda, 0xd6, 0x1d, 0xcb, 0xce, 0xac, 0xe1, 0x5f, 0x97, 0x45, 0x8f,
|
||||
0xc1, 0x64, 0x16, 0xa6, 0x88, 0x2a, 0x36, 0x4a, 0x76, 0x64, 0x8f, 0x83,
|
||||
0x7a, 0x1d, 0xd8, 0x91, 0x90, 0x7b, 0x58, 0xb8, 0x1c, 0x7f, 0x56, 0x57,
|
||||
0x35, 0xfb, 0xf3, 0x1a, 0xcb, 0x7c, 0x66, 0x66, 0x04, 0x95, 0xee, 0x3a,
|
||||
0x80, 0xf0, 0xd4, 0x12, 0x3a, 0x7e, 0x7e, 0x5e, 0xb8, 0x55, 0x29, 0x23,
|
||||
0x06, 0xd3, 0x85, 0x0c, 0x99, 0x91, 0x42, 0xee, 0x5a, 0x30, 0x7f, 0x52,
|
||||
0x20, 0xb3, 0xe2, 0xe7, 0x39, 0x69, 0xb6, 0xfc, 0x42, 0x1e, 0x98, 0xd3,
|
||||
0x31, 0xa2, 0xfa, 0x81, 0x52, 0x69, 0x6d, 0x23, 0xf8, 0xc4, 0xc3, 0x3c,
|
||||
0x9b, 0x48, 0x75, 0xa8, 0xc7, 0xe7, 0x61, 0x81, 0x1f, 0xf7, 0xce, 0x10,
|
||||
0xaa, 0x13, 0xcb, 0x6e, 0x19, 0xc0, 0x4f, 0x6f, 0x90, 0xa8, 0x41, 0xea,
|
||||
0x49, 0xdf, 0xe4, 0xef, 0x84, 0x54, 0xb5, 0x37, 0xaf, 0x12, 0x75, 0x1a,
|
||||
0x11, 0x4b, 0x58, 0x7f, 0x63, 0x22, 0x33, 0xb1, 0xc8, 0x4d, 0xf2, 0x41,
|
||||
0x10, 0xbc, 0x37, 0xb5, 0xd5, 0xb2, 0x21, 0x32, 0x35, 0x9d, 0xf3, 0x8d,
|
||||
0xab, 0x66, 0x9d, 0x19, 0x12, 0x71, 0x45, 0xb3, 0x82, 0x5a, 0x5c, 0xff,
|
||||
0x2d, 0xcf, 0xf4, 0x5b, 0x56, 0xb8, 0x08, 0xb3, 0xd2, 0x43, 0x8c, 0xac,
|
||||
0xd2, 0xf8, 0xcc, 0x6d, 0x90, 0x97, 0xff, 0x12, 0x74, 0x97, 0xf8, 0xa4,
|
||||
0xe3, 0x95, 0xae, 0x92, 0xdc, 0x7e, 0x9d, 0x2b, 0xb4, 0x94, 0xc3, 0x8d,
|
||||
0x80, 0xe7, 0x77, 0x5c, 0x5b, 0xbb, 0x43, 0xdc, 0xa6, 0xe9, 0xbe, 0x20,
|
||||
0xcc, 0x9d, 0x8e, 0xa4, 0x2b, 0xf2, 0x72, 0xdc, 0x44, 0x61, 0x0f, 0xad,
|
||||
0x1a, 0x5e, 0xa5, 0x48, 0xe4, 0x42, 0xc5, 0xe4, 0xf1, 0x6d, 0x33, 0xdb,
|
||||
0xb2, 0x1b, 0x9f, 0xb2, 0xff, 0x18, 0x0e, 0x62, 0x35, 0x99, 0xed, 0x22,
|
||||
0x19, 0x4a, 0x5e, 0xb3, 0x3c, 0x07, 0x8f, 0x6e, 0x22, 0x5b, 0x16, 0x4a,
|
||||
0x9f, 0xef, 0xf3, 0xe7, 0xd6, 0x48, 0xe1, 0xb4, 0x3b, 0xab, 0x1b, 0x9e,
|
||||
0x53, 0xd7, 0x1b, 0xd9, 0x2d, 0x51, 0x8f, 0xe4, 0x1c, 0xab, 0xdd, 0xb9,
|
||||
0xe2, 0xee, 0xe4, 0xdd, 0x60, 0x04, 0x86, 0x6b, 0x4e, 0x7a, 0xc8, 0x09,
|
||||
0x51, 0xd1, 0x9b, 0x36, 0x9a, 0x36, 0x7f, 0xe8, 0x6b, 0x09, 0x6c, 0xee,
|
||||
0xad, 0x3a, 0x2f, 0xa8, 0x63, 0x92, 0x23, 0x2f, 0x7e, 0x00, 0xe2, 0xd1,
|
||||
0xbb, 0xd9, 0x5b, 0x5b, 0xfa, 0x4b, 0x83, 0x00, 0x19, 0x28, 0xfb, 0x7e,
|
||||
0xfe, 0x58, 0xab, 0xb7, 0x33, 0x45, 0x8f, 0x75, 0x9a, 0x54, 0x3d, 0x77,
|
||||
0x06, 0x75, 0x61, 0x4f, 0x5c, 0x93, 0xa0, 0xf9, 0xe8, 0xcf, 0xf6, 0x04,
|
||||
0x14, 0xda, 0x1b, 0x2e, 0x79, 0x35, 0xb8, 0xb4, 0xfa, 0x08, 0x27, 0x9a,
|
||||
0x03, 0x70, 0x78, 0x97, 0x8f, 0xae, 0x2e, 0xd5, 0x1c, 0xe0, 0x4d, 0x91,
|
||||
0x3a, 0xfe, 0x1a, 0x64, 0xd8, 0x49, 0xdf, 0x6c, 0x66, 0xac, 0xc9, 0x57,
|
||||
0x06, 0x72, 0xc0, 0xc0, 0x09, 0x71, 0x6a, 0xd0, 0xb0, 0x7d, 0x35, 0x3f,
|
||||
0x53, 0x17, 0x49, 0x38, 0x92, 0x22, 0x55, 0xf6, 0x58, 0x56, 0xa2, 0x42,
|
||||
0x77, 0x94, 0xb7, 0x28, 0x0a, 0xa0, 0xd2, 0xda, 0x25, 0xc1, 0xcc, 0x52,
|
||||
0x51, 0xd6, 0xba, 0x18, 0x0f, 0x0d, 0xe3, 0x7d, 0xd1, 0xda, 0xd9, 0x0c,
|
||||
0x5e, 0x3a, 0xca, 0xe9, 0xf1, 0xf5, 0x65, 0xfc, 0xc3, 0x99, 0x72, 0x25,
|
||||
0xf2, 0xc0, 0xa1, 0x8c, 0x43, 0x9d, 0xb2, 0xc9, 0xb1, 0x1a, 0x24, 0x34,
|
||||
0x57, 0xd8, 0xa7, 0x52, 0xa3, 0x39, 0x6e, 0x0b, 0xec, 0xbd, 0x5e, 0xc9,
|
||||
0x1f, 0x74, 0xed, 0xae, 0xe6, 0x4e, 0x49, 0xe8, 0x87, 0x3e, 0x46, 0x0d,
|
||||
0x40, 0x30, 0xda, 0x9d, 0xcf, 0xf5, 0x03, 0x1f, 0x38, 0x29, 0x3b, 0x66,
|
||||
0xe5, 0xc0, 0x89, 0x4c, 0xfc, 0x09, 0x62, 0x37, 0x01, 0xf9, 0x01, 0xab,
|
||||
0x8d, 0x53, 0x9c, 0x36, 0x5d, 0x36, 0x66, 0x8d, 0x87, 0xf4, 0xab, 0x37,
|
||||
0xb7, 0xf7, 0xe3, 0xdf, 0xc1, 0x52, 0xc0, 0x1d, 0x09, 0x92, 0x21, 0x47,
|
||||
0x49, 0x9a, 0x19, 0x38, 0x05, 0x62, 0xf3, 0x47, 0x80, 0x89, 0x1e, 0x70,
|
||||
0xa1, 0x57, 0xb7, 0x72, 0xd0, 0x41, 0x7a, 0x5c, 0x6a, 0x13, 0x8b, 0x6c,
|
||||
0xda, 0xdf, 0x6b, 0x01, 0x15, 0x20, 0xfa, 0xc8, 0x67, 0xee, 0xb2, 0x13,
|
||||
0xd8, 0x5f, 0x84, 0x30, 0x44, 0x8e, 0xf9, 0x2a, 0xae, 0x17, 0x53, 0x49,
|
||||
0xaa, 0x34, 0x31, 0x12, 0x31, 0xec, 0xf3, 0x25, 0x27, 0x53, 0x6b, 0xb5,
|
||||
0x63, 0xa6, 0xbc, 0xf1, 0x77, 0xd4, 0xb4, 0x77, 0xd1, 0xee, 0xad, 0x62,
|
||||
0x9d, 0x2c, 0x2e, 0x11, 0x0a, 0xd1, 0x87, 0xfe, 0xef, 0x77, 0x0e, 0xd1,
|
||||
0x38, 0xfe, 0xcc, 0x88, 0xaa, 0x1c, 0x06, 0x93, 0x25, 0x56, 0xfe, 0x0c,
|
||||
0x52, 0xe9, 0x7f, 0x4c, 0x3b, 0x2a, 0xfb, 0x40, 0x62, 0x29, 0x0a, 0x1d,
|
||||
0x58, 0x78, 0x8b, 0x09, 0x25, 0xaa, 0xc6, 0x8f, 0x66, 0x8f, 0xd1, 0x93,
|
||||
0x5a, 0xd6, 0x68, 0x35, 0x69, 0x13, 0x5d, 0x42, 0x35, 0x95, 0xcb, 0xc4,
|
||||
0xec, 0x17, 0x92, 0x96, 0xcb, 0x4a, 0xb9, 0x8f, 0xe5, 0xc4, 0x4a, 0xe7,
|
||||
0x54, 0x52, 0x4c, 0x64, 0x06, 0xac, 0x2f, 0x13, 0x32, 0x02, 0x47, 0x13,
|
||||
0x5c, 0xa2, 0x66, 0xdc, 0x36, 0x0c, 0x4f, 0xbb, 0x89, 0x58, 0x85, 0x16,
|
||||
0xf1, 0xf1, 0xff, 0xd2, 0x86, 0x54, 0x29, 0xb3, 0x7e, 0x2a, 0xbd, 0xf9,
|
||||
0x53, 0x8c, 0xa0, 0x60, 0x60, 0xb2, 0x90, 0x7f, 0x3a, 0x11, 0x5f, 0x2a,
|
||||
0x50, 0x74, 0x2a, 0xd1, 0x68, 0x78, 0xdb, 0x31, 0x1b, 0x8b, 0xee, 0xee,
|
||||
0x18, 0x97, 0xf3, 0x50, 0x84, 0xc1, 0x8f, 0xe1, 0xc6, 0x01, 0xb4, 0x16,
|
||||
0x65, 0x25, 0x0c, 0x03, 0xab, 0xed, 0x4f, 0xd6, 0xe6, 0x16, 0x23, 0xcc,
|
||||
0x42, 0x93, 0xff, 0xfa, 0x92, 0x63, 0x33, 0x9e, 0x36, 0xb0, 0xdc, 0x9a,
|
||||
0xb6, 0xaa, 0xd7, 0x48, 0xfe, 0x27, 0x01, 0xcf, 0x67, 0xc0, 0x75, 0xa0,
|
||||
0x86, 0x9a, 0xec, 0xa7, 0x2e, 0xb8, 0x7b, 0x00, 0x7f, 0xd4, 0xe3, 0xb3,
|
||||
0xfc, 0x48, 0xab, 0x50, 0x20, 0xd4, 0x0d, 0x58, 0x26, 0xc0, 0x3c, 0x09,
|
||||
0x0b, 0x80, 0x9e, 0xaf, 0x14, 0x3c, 0x0c, 0x6e, 0x69, 0xbc, 0x6c, 0x4e,
|
||||
0x50, 0x33, 0xb0, 0x07, 0x64, 0x6e, 0x77, 0x96, 0xc2, 0xe6, 0x3b, 0xd7,
|
||||
0xfe, 0xdc, 0xa4, 0x2f, 0x18, 0x5b, 0x53, 0xe5, 0xdd, 0xb6, 0xce, 0xeb,
|
||||
0x16, 0xb4, 0x25, 0xc6, 0xcb, 0xf2, 0x65, 0x3c, 0x4f, 0x94, 0xa5, 0x11,
|
||||
0x18, 0xeb, 0x7b, 0x62, 0x1d, 0xd5, 0x02, 0x35, 0x76, 0xf6, 0xb5, 0x20,
|
||||
0x27, 0x21, 0x9b, 0xab, 0xf4, 0xb6, 0x8f, 0x1a, 0x70, 0x1d, 0x12, 0xe3,
|
||||
0xb9, 0x8e, 0x29, 0x52, 0x25, 0xf4, 0xba, 0xb4, 0x25, 0x2c, 0x91, 0x11,
|
||||
0xf2, 0xae, 0x7b, 0xbe, 0xb6, 0x67, 0xd6, 0x08, 0xf8, 0x6f, 0xe7, 0xb0,
|
||||
0x16, 0xc5, 0xf6, 0xd5, 0xfb, 0x07, 0x71, 0x5b, 0x0e, 0xe1, 0x02, 0x03,
|
||||
0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55,
|
||||
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xaa, 0xe7, 0x7f, 0xcf, 0xf8, 0xb4,
|
||||
0xe0, 0x8d, 0x39, 0x9a, 0x1d, 0x4f, 0x86, 0xa2, 0xac, 0x56, 0x32, 0xd9,
|
||||
0x58, 0xe3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
|
||||
0x16, 0x80, 0x14, 0xaa, 0xe7, 0x7f, 0xcf, 0xf8, 0xb4, 0xe0, 0x8d, 0x39,
|
||||
0x9a, 0x1d, 0x4f, 0x86, 0xa2, 0xac, 0x56, 0x32, 0xd9, 0x58, 0xe3, 0x30,
|
||||
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
|
||||
0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||||
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x04, 0x02, 0x00,
|
||||
0x00, 0x0a, 0x0a, 0x81, 0xb5, 0x2e, 0xac, 0x52, 0xab, 0x0f, 0xeb, 0xad,
|
||||
0x96, 0xd6, 0xd6, 0x59, 0x8f, 0x55, 0x15, 0x56, 0x70, 0xda, 0xd5, 0x75,
|
||||
0x47, 0x12, 0x9a, 0x0e, 0xd1, 0x65, 0x68, 0xe0, 0x51, 0x89, 0x59, 0xcc,
|
||||
0xe3, 0x5a, 0x1b, 0x85, 0x14, 0xa3, 0x1d, 0x9b, 0x3f, 0xd1, 0xa4, 0x42,
|
||||
0xb0, 0x89, 0x12, 0x93, 0xd3, 0x54, 0x19, 0x04, 0xa2, 0xaf, 0xaa, 0x60,
|
||||
0xca, 0x03, 0xc2, 0xae, 0x62, 0x8c, 0xb6, 0x31, 0x03, 0xd6, 0xa5, 0xf3,
|
||||
0x5e, 0x8d, 0x5c, 0x69, 0x4c, 0x7d, 0x81, 0x49, 0x20, 0x25, 0x41, 0xa4,
|
||||
0x2a, 0x95, 0x87, 0x36, 0xa3, 0x9b, 0x9e, 0x9f, 0xed, 0x85, 0xf3, 0xb1,
|
||||
0xf1, 0xe9, 0x1b, 0xbb, 0xe3, 0xbc, 0x3b, 0x11, 0x36, 0xca, 0xb9, 0x5f,
|
||||
0xee, 0x64, 0xde, 0x2a, 0x99, 0x27, 0x91, 0xc0, 0x54, 0x9e, 0x7a, 0xd4,
|
||||
0x89, 0x8c, 0xa0, 0xe3, 0xfd, 0x44, 0x6f, 0x02, 0x38, 0x3c, 0xee, 0x52,
|
||||
0x48, 0x1b, 0xd4, 0x25, 0x2b, 0xcb, 0x8e, 0xa8, 0x1b, 0x09, 0xd6, 0x30,
|
||||
0x51, 0x15, 0x6c, 0x5c, 0x03, 0x76, 0xad, 0x64, 0x45, 0x50, 0xa2, 0xe1,
|
||||
0x3c, 0x5a, 0x67, 0x87, 0xff, 0x8c, 0xed, 0x9a, 0x8d, 0x04, 0xc1, 0xac,
|
||||
0xf9, 0xca, 0xf5, 0x2a, 0x05, 0x9c, 0xdd, 0x78, 0xce, 0x99, 0x78, 0x7b,
|
||||
0xcd, 0x43, 0x10, 0x40, 0xf7, 0xb5, 0x27, 0x12, 0xec, 0xe9, 0xb2, 0x3f,
|
||||
0xf4, 0x5d, 0xd9, 0xbb, 0xf8, 0xc4, 0xc9, 0xa4, 0x46, 0x20, 0x41, 0x7f,
|
||||
0xeb, 0x79, 0xb0, 0x51, 0x8c, 0xf7, 0xc3, 0x2c, 0x16, 0xfe, 0x42, 0x59,
|
||||
0x77, 0xfe, 0x53, 0xfe, 0x19, 0x57, 0x58, 0x44, 0x6d, 0x12, 0xe2, 0x95,
|
||||
0xd0, 0xd3, 0x5a, 0xb5, 0x2d, 0xe5, 0x7e, 0xb4, 0xb3, 0xa9, 0xcc, 0x7d,
|
||||
0x53, 0x77, 0x81, 0x01, 0x0f, 0x0a, 0xf6, 0x86, 0x3c, 0x7d, 0xb5, 0x2c,
|
||||
0xbf, 0x62, 0xc3, 0xf5, 0x38, 0x89, 0x13, 0x84, 0x1f, 0x44, 0x2d, 0x87,
|
||||
0x5c, 0x23, 0x9e, 0x05, 0x62, 0x56, 0x3d, 0x71, 0x4d, 0xd0, 0xe3, 0x15,
|
||||
0xe9, 0x09, 0x9c, 0x1a, 0xc0, 0x9a, 0x19, 0x8b, 0x9c, 0xe9, 0xae, 0xde,
|
||||
0x62, 0x05, 0x23, 0xe2, 0xd0, 0x3f, 0xf5, 0xef, 0x04, 0x96, 0x4c, 0x87,
|
||||
0x34, 0x2f, 0xd5, 0x90, 0xde, 0xbf, 0x4b, 0x56, 0x12, 0x5f, 0xc6, 0xdc,
|
||||
0xa4, 0x1c, 0xc4, 0x53, 0x0c, 0xf9, 0xb4, 0xe4, 0x2c, 0xe7, 0x48, 0xbd,
|
||||
0xb1, 0xac, 0xf1, 0xc1, 0x8d, 0x53, 0x47, 0x84, 0xc0, 0x78, 0x0a, 0x5e,
|
||||
0xc2, 0x16, 0xff, 0xef, 0x97, 0x5b, 0x33, 0x85, 0x92, 0xcd, 0xd4, 0xbb,
|
||||
0x64, 0xee, 0xed, 0x17, 0x18, 0x43, 0x32, 0x99, 0x32, 0x36, 0x25, 0xf4,
|
||||
0x21, 0x3c, 0x2f, 0x55, 0xdc, 0x16, 0x06, 0x4d, 0x86, 0xa3, 0xa9, 0x34,
|
||||
0x22, 0xd5, 0xc3, 0xc8, 0x64, 0x3c, 0x4e, 0x3a, 0x69, 0xbd, 0xcf, 0xd7,
|
||||
0xee, 0x3f, 0x0d, 0x15, 0xeb, 0xfb, 0xbd, 0x91, 0x7f, 0xef, 0x48, 0xec,
|
||||
0x86, 0xb2, 0x78, 0xf7, 0x53, 0x90, 0x38, 0xb5, 0x04, 0x9c, 0xb7, 0xd7,
|
||||
0x9e, 0xaa, 0x15, 0xf7, 0xcd, 0xc2, 0x17, 0xd5, 0x8f, 0x82, 0x98, 0xa3,
|
||||
0xaf, 0x59, 0xf1, 0x71, 0xda, 0x6e, 0xaf, 0x97, 0x6d, 0x77, 0x72, 0xfd,
|
||||
0xa8, 0x80, 0x25, 0xce, 0x46, 0x04, 0x6e, 0x40, 0x15, 0x24, 0xc0, 0xf9,
|
||||
0xbf, 0x13, 0x16, 0x72, 0xcb, 0xb7, 0x10, 0xc7, 0x0a, 0xd6, 0x66, 0x96,
|
||||
0x5b, 0x27, 0x4d, 0x66, 0xc4, 0x2f, 0x21, 0x90, 0x9f, 0x8c, 0x24, 0xa0,
|
||||
0x0e, 0xa2, 0x89, 0x92, 0xd2, 0x44, 0x63, 0x06, 0xb2, 0xab, 0x07, 0x26,
|
||||
0xde, 0x03, 0x1d, 0xdb, 0x2a, 0x42, 0x5b, 0x4c, 0xf6, 0xfe, 0x53, 0xfa,
|
||||
0x80, 0x45, 0x8d, 0x75, 0xf6, 0x0e, 0x1d, 0xcc, 0x4c, 0x3b, 0xb0, 0x80,
|
||||
0x6d, 0x4c, 0xed, 0x7c, 0xe0, 0xd2, 0xe7, 0x62, 0x59, 0xb1, 0x5a, 0x5d,
|
||||
0x3a, 0xec, 0x86, 0x04, 0xfe, 0x26, 0xd1, 0x18, 0xed, 0x56, 0x7d, 0x67,
|
||||
0x56, 0x24, 0x6d, 0x7c, 0x6e, 0x8f, 0xc8, 0xa0, 0xba, 0x42, 0x0a, 0x33,
|
||||
0x38, 0x7a, 0x09, 0x03, 0xc2, 0xbf, 0x9b, 0x01, 0xdd, 0x03, 0x5a, 0xba,
|
||||
0x76, 0x04, 0xb1, 0xc3, 0x40, 0x23, 0x53, 0xbd, 0x64, 0x4e, 0x0f, 0xe7,
|
||||
0xc3, 0x4e, 0x48, 0xea, 0x19, 0x2b, 0x1c, 0xe4, 0x3d, 0x93, 0xd8, 0xf6,
|
||||
0xfb, 0xda, 0x3d, 0xeb, 0xed, 0xc2, 0xbd, 0x14, 0x57, 0x40, 0xde, 0xd1,
|
||||
0x74, 0x54, 0x1b, 0xa8, 0x39, 0xda, 0x73, 0x56, 0xd4, 0xbe, 0xab, 0xec,
|
||||
0xc7, 0x17, 0x4f, 0x91, 0xb6, 0xf6, 0xcb, 0x24, 0xc6, 0x1c, 0x07, 0xc4,
|
||||
0xf3, 0xd0, 0x5e, 0x8d, 0xfa, 0x44, 0x98, 0x5c, 0x87, 0x36, 0x75, 0xb6,
|
||||
0xa5, 0x31, 0xaa, 0xab, 0x7d, 0x38, 0x66, 0xb3, 0x18, 0x58, 0x65, 0x97,
|
||||
0x06, 0xfd, 0x61, 0x81, 0x71, 0xc5, 0x17, 0x8b, 0x19, 0x03, 0xc8, 0x58,
|
||||
0xec, 0x05, 0xca, 0x7b, 0x0f, 0xec, 0x9d, 0xb4, 0xbc, 0xa3, 0x20, 0x2e,
|
||||
0xf8, 0xe4, 0xb1, 0x82, 0xdc, 0x5a, 0xd2, 0x92, 0x9c, 0x43, 0x5d, 0x16,
|
||||
0x5b, 0x90, 0x80, 0xe4, 0xfb, 0x6e, 0x24, 0x6b, 0x8c, 0x1a, 0x35, 0xab,
|
||||
0xbd, 0x77, 0x7f, 0xf9, 0x61, 0x80, 0xa5, 0xab, 0xa3, 0x39, 0xc2, 0xc9,
|
||||
0x69, 0x3c, 0xfc, 0xb3, 0x9a, 0x05, 0x45, 0x03, 0x88, 0x8f, 0x8e, 0x23,
|
||||
0xf2, 0x0c, 0x4c, 0x54, 0xb9, 0x40, 0x3a, 0x31, 0x1a, 0x22, 0x67, 0x43,
|
||||
0x4a, 0x3e, 0xa0, 0x8c, 0x2d, 0x4d, 0x4f, 0xfc, 0xb5, 0x9b, 0x1f, 0xe1,
|
||||
0xef, 0x02, 0x54, 0xab, 0x8d, 0x75, 0x4d, 0x93, 0xba, 0x76, 0xe1, 0xbc,
|
||||
0x42, 0x7f, 0x6c, 0xcb, 0xf5, 0x47, 0xd6, 0x8a, 0xac, 0x5d, 0xe9, 0xbb,
|
||||
0x3a, 0x65, 0x2c, 0x81, 0xe5, 0xff, 0x27, 0x7e, 0x60, 0x64, 0x80, 0x42,
|
||||
0x8d, 0x36, 0x6b, 0x07, 0x76, 0x6a, 0xf1, 0xdf, 0x96, 0x17, 0x93, 0x21,
|
||||
0x5d, 0xe4, 0x6c, 0xce, 0x1c, 0xb9, 0x82, 0x45, 0x05, 0x61, 0xe2, 0x41,
|
||||
0x96, 0x03, 0x7d, 0x10, 0x8b, 0x3e, 0xc7, 0xe5, 0xcf, 0x08, 0xeb, 0x81,
|
||||
0xd3, 0x82, 0x1b, 0x04, 0x96, 0x93, 0x5a, 0xe2, 0x8c, 0x8e, 0x50, 0x33,
|
||||
0xf6, 0xf9, 0xf0, 0xfb, 0xb1, 0xd7, 0xc6, 0x97, 0xaa, 0xef, 0x0b, 0x87,
|
||||
0xe1, 0x34, 0x97, 0x78, 0x2e, 0x7c, 0x46, 0x11, 0xd5, 0x3c, 0xec, 0x38,
|
||||
0x70, 0x59, 0x14, 0x65, 0x4d, 0x0e, 0xd1, 0xeb, 0x49, 0xb3, 0x99, 0x6f,
|
||||
0x87, 0xf1, 0x79, 0x21, 0xd9, 0x5c, 0x37, 0xb2, 0xfe, 0xc4, 0x7a, 0xc1,
|
||||
0x67, 0xbd, 0x02, 0xfc, 0x02, 0xab, 0x2f, 0xf5, 0x0f, 0xa7, 0xae, 0x90,
|
||||
0xc2, 0xaf, 0xdb, 0xd1, 0x96, 0xb2, 0x92, 0x5a, 0xfb, 0xca, 0x28, 0x74,
|
||||
0x17, 0xed, 0xda, 0x2c, 0x9f, 0xb4, 0x2d, 0xf5, 0x71, 0x20, 0x64, 0x2d,
|
||||
0x44, 0xe5, 0xa3, 0xa0, 0x94, 0x6f, 0x20, 0xb3, 0x73, 0x96, 0x40, 0x06,
|
||||
0x9b, 0x25, 0x47, 0x4b, 0xe0, 0x63, 0x91, 0xd9, 0xda, 0xf3, 0xc3, 0xe5,
|
||||
0x3a, 0x3c, 0xb7, 0x5f, 0xab, 0x1e, 0x51, 0x17, 0x4f, 0xec, 0xc1, 0x6d,
|
||||
0x82, 0x79, 0x8e, 0xba, 0x7c, 0x47, 0x8e, 0x99, 0x00, 0x17, 0x9e, 0xda,
|
||||
0x10, 0x42, 0x70, 0x25, 0x42, 0x84, 0xc8, 0xb1, 0x95, 0x56, 0xb2, 0x08,
|
||||
0xa0, 0x4f, 0xdc, 0xcd, 0x9e, 0x31, 0x4b, 0x0c, 0x0b, 0x03, 0x5d, 0x2c,
|
||||
0x26, 0xbc, 0xa9, 0x4b, 0x19, 0xdf, 0x90, 0x01, 0x9a, 0xe0, 0x06, 0x05,
|
||||
0x13, 0x34, 0x9d, 0x34, 0xb8, 0xef, 0x13, 0x3a, 0x20, 0xf5, 0x74, 0x02,
|
||||
0x70, 0x3b, 0x41, 0x60, 0x1f, 0x5e, 0x76, 0x0a, 0xb1, 0x17, 0xd5, 0xcf,
|
||||
0x79, 0xef, 0xf7, 0xab, 0xe7, 0xd6, 0x0f, 0xad, 0x85, 0x2c, 0x52, 0x67,
|
||||
0xb5, 0xa0, 0x4a, 0xfd, 0xaf};
|
@ -475,6 +475,45 @@ TEST_P(TlsConnectTls13, NamedGroupMismatch13) {
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
}
|
||||
|
||||
// Replace the key share in the server key exchange message with one that's
|
||||
// larger than 8192 bits.
|
||||
class TooLongDHEServerKEXFilter : public TlsHandshakeFilter {
|
||||
public:
|
||||
TooLongDHEServerKEXFilter(const std::shared_ptr<TlsAgent>& server)
|
||||
: TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
// Replace the server key exchange message very large DH shares that are
|
||||
// not supported by NSS.
|
||||
const uint32_t share_len = 0x401;
|
||||
const uint8_t zero_share[share_len] = {0x80};
|
||||
size_t offset = 0;
|
||||
// Write dh_p.
|
||||
offset = output->Write(offset, share_len, 2);
|
||||
offset = output->Write(offset, zero_share, share_len);
|
||||
// Write dh_g.
|
||||
offset = output->Write(offset, share_len, 2);
|
||||
offset = output->Write(offset, zero_share, share_len);
|
||||
// Write dh_Y.
|
||||
offset = output->Write(offset, share_len, 2);
|
||||
offset = output->Write(offset, zero_share, share_len);
|
||||
|
||||
return CHANGE;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectGenericPre13, TooBigDHGroup) {
|
||||
EnableOnlyDheCiphers();
|
||||
MakeTlsFilter<TooLongDHEServerKEXFilter>(server_);
|
||||
client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_FALSE);
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
client_->CheckErrorCode(SSL_ERROR_DH_KEY_TOO_LONG);
|
||||
}
|
||||
|
||||
// Even though the client doesn't have DHE groups enabled the server assumes it
|
||||
// does. The client requires named groups and thus does not accept FF3072 as
|
||||
// custom group in contrast to the previous test.
|
||||
|
@ -321,7 +321,15 @@ TEST_P(TlsExtensionTestGeneric, AlpnMissingValue) {
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnZeroLength) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = {0x01, 0x61, 0x00};
|
||||
const uint8_t val[] = {0x00, 0x03, 0x01, 0x61, 0x00};
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
|
||||
client_, ssl_app_layer_protocol_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnLengthOverflow) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = {0x00, 0x03, 0x01, 0x61, 0x01};
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
|
||||
client_, ssl_app_layer_protocol_xtn, extension));
|
||||
|
@ -617,6 +617,68 @@ TEST_P(TlsConnectTls13, RetryStatefulDropCookie) {
|
||||
server_->CheckErrorCode(SSL_ERROR_MISSING_COOKIE_EXTENSION);
|
||||
}
|
||||
|
||||
class TruncateHrrCookie : public TlsExtensionFilter {
|
||||
public:
|
||||
TruncateHrrCookie(const std::shared_ptr<TlsAgent>& a)
|
||||
: TlsExtensionFilter(a) {}
|
||||
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
if (extension_type != ssl_tls13_cookie_xtn) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
// Claim a zero-length cookie.
|
||||
output->Allocate(2);
|
||||
output->Write(0, static_cast<uint32_t>(0), 2);
|
||||
return CHANGE;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectTls13, RetryCookieEmpty) {
|
||||
ConfigureSelfEncrypt();
|
||||
EnsureTlsSetup();
|
||||
|
||||
TriggerHelloRetryRequest(client_, server_);
|
||||
MakeTlsFilter<TruncateHrrCookie>(client_);
|
||||
|
||||
ExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
Handshake();
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
}
|
||||
|
||||
class AddJunkToCookie : public TlsExtensionFilter {
|
||||
public:
|
||||
AddJunkToCookie(const std::shared_ptr<TlsAgent>& a) : TlsExtensionFilter(a) {}
|
||||
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
if (extension_type != ssl_tls13_cookie_xtn) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
*output = input;
|
||||
// Add junk after the cookie.
|
||||
static const uint8_t junk[2] = {1, 2};
|
||||
output->Append(DataBuffer(junk, sizeof(junk)));
|
||||
return CHANGE;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectTls13, RetryCookieWithExtras) {
|
||||
ConfigureSelfEncrypt();
|
||||
EnsureTlsSetup();
|
||||
|
||||
TriggerHelloRetryRequest(client_, server_);
|
||||
MakeTlsFilter<AddJunkToCookie>(client_);
|
||||
|
||||
ExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
Handshake();
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
}
|
||||
|
||||
// Stream only because DTLS drops bad packets.
|
||||
TEST_F(TlsConnectStreamTls13, RetryStatelessDamageFirstClientHello) {
|
||||
ConfigureSelfEncrypt();
|
||||
|
@ -21,6 +21,7 @@ extern "C" {
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
#include "rsa8193.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
@ -100,4 +101,39 @@ TEST_P(TlsConnectStreamPre13,
|
||||
Connect();
|
||||
}
|
||||
|
||||
// Replace the server certificate with one that uses 8193-bit RSA.
|
||||
class TooLargeRSACertFilter : public TlsHandshakeFilter {
|
||||
public:
|
||||
TooLargeRSACertFilter(const std::shared_ptr<TlsAgent> &server)
|
||||
: TlsHandshakeFilter(server, {kTlsHandshakeCertificate}) {}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
|
||||
const DataBuffer &input,
|
||||
DataBuffer *output) {
|
||||
const uint32_t cert_len = sizeof(rsa8193);
|
||||
const uint32_t outer_len = cert_len + 3;
|
||||
size_t offset = 0;
|
||||
offset = output->Write(offset, outer_len, 3);
|
||||
offset = output->Write(offset, cert_len, 3);
|
||||
offset = output->Write(offset, rsa8193, cert_len);
|
||||
|
||||
return CHANGE;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectGenericPre13, TooLargeRSAKeyInCert) {
|
||||
EnableOnlyStaticRsaCiphers();
|
||||
MakeTlsFilter<TooLargeRSACertFilter>(server_);
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
client_->CheckErrorCode(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ServerAuthBiggestRsa) {
|
||||
Reset(TlsAgent::kRsa8192);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
@ -436,4 +436,20 @@ TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) {
|
||||
EXPECT_EQ(0U, session_id_len);
|
||||
}
|
||||
|
||||
TEST_F(Tls13CompatTest, ConnectWith12ThenAttemptToResume13CompatMode) {
|
||||
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
Connect();
|
||||
|
||||
Reset();
|
||||
ExpectResumption(RESUME_NONE);
|
||||
version_ = SSL_LIBRARY_VERSION_TLS_1_3;
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
EnableCompatMode();
|
||||
Connect();
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
@ -33,6 +33,7 @@ const char* TlsAgent::states[] = {"INIT", "CONNECTING", "CONNECTED", "ERROR"};
|
||||
|
||||
const std::string TlsAgent::kClient = "client"; // both sign and encrypt
|
||||
const std::string TlsAgent::kRsa2048 = "rsa2048"; // bigger
|
||||
const std::string TlsAgent::kRsa8192 = "rsa8192"; // biggest allowed
|
||||
const std::string TlsAgent::kServerRsa = "rsa"; // both sign and encrypt
|
||||
const std::string TlsAgent::kServerRsaSign = "rsa_sign";
|
||||
const std::string TlsAgent::kServerRsaPss = "rsa_pss";
|
||||
|
@ -69,6 +69,7 @@ class TlsAgent : public PollTarget {
|
||||
|
||||
static const std::string kClient; // the client key is sign only
|
||||
static const std::string kRsa2048; // bigger sign and encrypt for either
|
||||
static const std::string kRsa8192; // biggest sign and encrypt for either
|
||||
static const std::string kServerRsa; // both sign and encrypt
|
||||
static const std::string kServerRsaSign;
|
||||
static const std::string kServerRsaPss;
|
||||
|
@ -813,6 +813,7 @@ sec_pkcs12_decoder_asafes_notify(void *arg, PRBool before, void *dest,
|
||||
unsigned int cnt = p12dcx->safeContentsCnt - 1;
|
||||
safeContentsCtx = p12dcx->safeContentsList[cnt];
|
||||
if (safeContentsCtx->safeContentsA1Dcx) {
|
||||
SEC_ASN1DecoderClearFilterProc(p12dcx->aSafeA1Dcx);
|
||||
SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
|
||||
safeContentsCtx->safeContentsA1Dcx = NULL;
|
||||
}
|
||||
|
@ -560,6 +560,7 @@ sec_pkcs7_decoder_start_decrypt(SEC_PKCS7DecoderContext *p7dcx, int depth,
|
||||
return SECSuccess;
|
||||
|
||||
no_decryption:
|
||||
PK11_FreeSymKey(bulkkey);
|
||||
/*
|
||||
* For some reason (error set already, if appropriate), we cannot
|
||||
* decrypt the content. I am not sure what exactly is the right
|
||||
@ -1031,6 +1032,11 @@ SECStatus
|
||||
SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx,
|
||||
const char *buf, unsigned long len)
|
||||
{
|
||||
if (!p7dcx) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (p7dcx->cinfo != NULL && p7dcx->dcx != NULL) {
|
||||
PORT_Assert(p7dcx->error == 0);
|
||||
if (p7dcx->error == 0) {
|
||||
|
@ -549,3 +549,6 @@ ER3(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR, (SSL_ERROR_BASE + 173),
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_DTLS_ACK, (SSL_ERROR_BASE + 174),
|
||||
"SSL received a malformed DTLS ACK")
|
||||
|
||||
ER3(SSL_ERROR_DH_KEY_TOO_LONG, (SSL_ERROR_BASE + 175),
|
||||
"SSL received a DH key share that's too long (>8192 bit).")
|
||||
|
@ -5572,13 +5572,20 @@ ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
|
||||
}
|
||||
|
||||
/* Get the wrapped (encrypted) pre-master secret, enc_pms */
|
||||
enc_pms.len = SECKEY_PublicKeyStrength(svrPubKey);
|
||||
unsigned int svrPubKeyBits = SECKEY_PublicKeyStrengthInBits(svrPubKey);
|
||||
enc_pms.len = (svrPubKeyBits + 7) / 8;
|
||||
/* Check that the RSA key isn't larger than 8k bit. */
|
||||
if (svrPubKeyBits > SSL_MAX_RSA_KEY_BITS) {
|
||||
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
goto loser;
|
||||
}
|
||||
enc_pms.data = (unsigned char *)PORT_Alloc(enc_pms.len);
|
||||
if (enc_pms.data == NULL) {
|
||||
goto loser; /* err set by PORT_Alloc */
|
||||
}
|
||||
|
||||
/* wrap pre-master secret in server's public key. */
|
||||
/* Wrap pre-master secret in server's public key. */
|
||||
rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms);
|
||||
if (rv != SECSuccess) {
|
||||
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
|
||||
@ -5681,7 +5688,7 @@ ssl3_SendDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
|
||||
};
|
||||
sslEphemeralKeyPair *keyPair = NULL;
|
||||
SECKEYPublicKey *pubKey;
|
||||
PRUint8 dhData[1026]; /* Enough for the 8192-bit group. */
|
||||
PRUint8 dhData[SSL_MAX_DH_KEY_BITS / 8 + 2];
|
||||
sslBuffer dhBuf = SSL_BUFFER(dhData);
|
||||
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
@ -6164,28 +6171,38 @@ ssl_ClientSetCipherSuite(sslSocket *ss, SSL3ProtocolVersion version,
|
||||
static PRBool
|
||||
ssl_CheckServerSessionIdCorrectness(sslSocket *ss, SECItem *sidBytes)
|
||||
{
|
||||
PRBool sid_match = PR_FALSE;
|
||||
PRBool sent_fake_sid = ss->opt.enableTls13CompatMode && !IS_DTLS(ss);
|
||||
sslSessionID *sid = ss->sec.ci.sid;
|
||||
PRBool sidMatch = PR_FALSE;
|
||||
PRBool sentFakeSid = PR_FALSE;
|
||||
PRBool sentRealSid = sid && sid->version < SSL_LIBRARY_VERSION_TLS_1_3;
|
||||
|
||||
/* If in compat mode and we received a session ID with the right length
|
||||
* then compare it to the fake one we sent in the ClientHello. */
|
||||
if (sent_fake_sid && sidBytes->len == SSL3_SESSIONID_BYTES) {
|
||||
PRUint8 buf[SSL3_SESSIONID_BYTES];
|
||||
ssl_MakeFakeSid(ss, buf);
|
||||
sid_match = PORT_Memcmp(buf, sidBytes->data, sidBytes->len) == 0;
|
||||
/* If attempting to resume a TLS 1.2 connection, the session ID won't be a
|
||||
* fake. Check for the real value. */
|
||||
if (sentRealSid) {
|
||||
sidMatch = (sidBytes->len == sid->u.ssl3.sessionIDLength) &&
|
||||
PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes->data, sidBytes->len) == 0;
|
||||
} else {
|
||||
/* Otherwise, the session ID was a fake if TLS 1.3 compat mode is
|
||||
* enabled. If so, check for the fake value. */
|
||||
sentFakeSid = ss->opt.enableTls13CompatMode && !IS_DTLS(ss);
|
||||
if (sentFakeSid && sidBytes->len == SSL3_SESSIONID_BYTES) {
|
||||
PRUint8 buf[SSL3_SESSIONID_BYTES];
|
||||
ssl_MakeFakeSid(ss, buf);
|
||||
sidMatch = PORT_Memcmp(buf, sidBytes->data, sidBytes->len) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* TLS 1.2: SessionID shouldn't match the fake one. */
|
||||
/* TLS 1.2: Session ID shouldn't match if we sent a fake. */
|
||||
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
return !sid_match;
|
||||
return !sentFakeSid || !sidMatch;
|
||||
}
|
||||
|
||||
/* TLS 1.3: [Compat Mode] Session ID should match the fake one. */
|
||||
if (sent_fake_sid) {
|
||||
return sid_match;
|
||||
/* TLS 1.3: We sent a session ID. The server's should match. */
|
||||
if (sentRealSid || sentFakeSid) {
|
||||
return sidMatch;
|
||||
}
|
||||
|
||||
/* TLS 1.3: [Non-Compat Mode] Server shouldn't send a session ID. */
|
||||
/* TLS 1.3: The server shouldn't send a session ID. */
|
||||
return sidBytes->len == 0;
|
||||
}
|
||||
|
||||
@ -6718,6 +6735,10 @@ ssl_HandleDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
|
||||
errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
|
||||
goto alert_loser;
|
||||
}
|
||||
if (dh_p_bits > SSL_MAX_DH_KEY_BITS) {
|
||||
errCode = SSL_ERROR_DH_KEY_TOO_LONG;
|
||||
goto alert_loser;
|
||||
}
|
||||
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser; /* malformed. */
|
||||
|
@ -256,7 +256,8 @@ ssl_PopulateKeyPair(sslServerCert *sc, sslKeyPair *keyPair)
|
||||
|
||||
/* Get the size of the cert's public key, and remember it. */
|
||||
sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey);
|
||||
if (sc->serverKeyBits == 0) {
|
||||
if (sc->serverKeyBits == 0 ||
|
||||
(keyType == rsaKey && sc->serverKeyBits > SSL_MAX_RSA_KEY_BITS)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -263,6 +263,7 @@ typedef enum {
|
||||
SSL_ERROR_HANDSHAKE_FAILED = (SSL_ERROR_BASE + 172),
|
||||
SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR = (SSL_ERROR_BASE + 173),
|
||||
SSL_ERROR_RX_MALFORMED_DTLS_ACK = (SSL_ERROR_BASE + 174),
|
||||
SSL_ERROR_DH_KEY_TOO_LONG = (SSL_ERROR_BASE + 175),
|
||||
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
|
||||
} SSLErrorCodes;
|
||||
#endif /* NO_SECURITY_ERROR_ENUM */
|
||||
|
@ -121,6 +121,10 @@ typedef enum { SSLAppOpRead = 0,
|
||||
/* default number of entries in namedGroupPreferences */
|
||||
#define SSL_NAMED_GROUP_COUNT 31
|
||||
|
||||
/* The maximum DH and RSA bit-length supported. */
|
||||
#define SSL_MAX_DH_KEY_BITS 8192
|
||||
#define SSL_MAX_RSA_KEY_BITS 8192
|
||||
|
||||
/* Types and names of elliptic curves used in TLS */
|
||||
typedef enum {
|
||||
ec_type_explicitPrime = 1, /* not supported */
|
||||
@ -811,7 +815,7 @@ struct ssl3DHParamsStr {
|
||||
};
|
||||
|
||||
typedef struct SSLWrappedSymWrappingKeyStr {
|
||||
PRUint8 wrappedSymmetricWrappingkey[512];
|
||||
PRUint8 wrappedSymmetricWrappingkey[SSL_MAX_RSA_KEY_BITS / 8];
|
||||
CK_MECHANISM_TYPE symWrapMechanism;
|
||||
/* unwrapped symmetric wrapping key uses this mechanism */
|
||||
CK_MECHANISM_TYPE asymWrapMechanism;
|
||||
|
@ -860,12 +860,12 @@ tls13_ServerHandleCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
||||
}
|
||||
|
||||
if (xtnData->cookie.len == 0) {
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (data->len) {
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ static int /* bool */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sprintf(buf, " [%d]", k);
|
||||
sprintf(buf, " [%lu]", k);
|
||||
}
|
||||
buf += strlen(buf);
|
||||
|
||||
@ -982,7 +982,7 @@ sec_asn1d_prepare_for_contents(sec_asn1d_state *state)
|
||||
|
||||
#ifdef DEBUG_ASN1D_STATES
|
||||
{
|
||||
printf("Found Length %d %s\n", state->contents_length,
|
||||
printf("Found Length %lu %s\n", state->contents_length,
|
||||
state->indefinite ? "indefinite" : "");
|
||||
}
|
||||
#endif
|
||||
@ -2717,16 +2717,15 @@ dump_states(SEC_ASN1DecoderContext *cx)
|
||||
}
|
||||
|
||||
i = formatKind(state->theTemplate->kind, kindBuf);
|
||||
printf("%s: tmpl %08x, kind%s",
|
||||
printf("%s: tmpl kind %s",
|
||||
(state == cx->current) ? "STATE" : "State",
|
||||
state->theTemplate,
|
||||
kindBuf);
|
||||
printf(" %s", (state->place >= 0 && state->place <= notInUse) ? place_names[state->place] : "(undefined)");
|
||||
if (!i)
|
||||
printf(", expect 0x%02x",
|
||||
printf(", expect 0x%02lx",
|
||||
state->expect_tag_number | state->expect_tag_modifiers);
|
||||
|
||||
printf("%s%s%s %d\n",
|
||||
printf("%s%s%s %lu\n",
|
||||
state->indefinite ? ", indef" : "",
|
||||
state->missing ? ", miss" : "",
|
||||
state->endofcontents ? ", EOC" : "",
|
||||
@ -2754,7 +2753,7 @@ SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
|
||||
what = SEC_ASN1_Contents;
|
||||
consumed = 0;
|
||||
#ifdef DEBUG_ASN1D_STATES
|
||||
printf("\nPLACE = %s, next byte = 0x%02x, %08x[%d]\n",
|
||||
printf("\nPLACE = %s, next byte = 0x%02x, %p[%lu]\n",
|
||||
(state->place >= 0 && state->place <= notInUse) ? place_names[state->place] : "(undefined)",
|
||||
len ? (unsigned int)((unsigned char *)buf)[consumed] : 0,
|
||||
buf, consumed);
|
||||
@ -2977,7 +2976,7 @@ SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
if (cx->status == needBytes) {
|
||||
if (!cx || cx->status == needBytes) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
|
@ -47,6 +47,7 @@ make_cert() {
|
||||
dsa) type_args='-g 1024' ;;
|
||||
rsa) type_args='-g 1024' ;;
|
||||
rsa2048) type_args='-g 2048';type=rsa ;;
|
||||
rsa8192) type_args='-g 8192';type=rsa ;;
|
||||
rsapss) type_args='-g 1024 --pss';type=rsa ;;
|
||||
p256) type_args='-q nistp256';type=ec ;;
|
||||
p384) type_args='-q secp384r1';type=ec ;;
|
||||
@ -83,6 +84,7 @@ ssl_gtest_certs() {
|
||||
make_cert client rsa sign
|
||||
make_cert rsa rsa sign kex
|
||||
make_cert rsa2048 rsa2048 sign kex
|
||||
make_cert rsa8192 rsa8192 sign kex
|
||||
make_cert rsa_sign rsa sign
|
||||
make_cert rsa_pss rsapss sign
|
||||
make_cert rsa_decrypt rsa kex
|
||||
|
@ -665,7 +665,7 @@ impl<'le> GeckoElement<'le> {
|
||||
fn non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent {
|
||||
debug_assert!(!self.is_xul_element());
|
||||
self.extended_slots()
|
||||
.map_or(ptr::null_mut(), |slots| slots._base.mBindingParent)
|
||||
.map_or(ptr::null_mut(), |slots| slots._base.mBindingParent.raw::<nsIContent>())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -57,7 +57,17 @@ public:
|
||||
*/
|
||||
bool RemoveObserver(Observer<T>* aObserver)
|
||||
{
|
||||
return mObservers.RemoveElement(aObserver);
|
||||
if (mObservers.RemoveElement(aObserver)) {
|
||||
if (!mBroadcastCopy.IsEmpty()) {
|
||||
// Annoyingly, someone could RemoveObserver() an item on the list
|
||||
// while we're in a Broadcast()'s Notify() call.
|
||||
auto i = mBroadcastCopy.IndexOf(aObserver);
|
||||
MOZ_ASSERT(i != mBroadcastCopy.NoIndex);
|
||||
mBroadcastCopy[i] = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t Length()
|
||||
@ -65,17 +75,27 @@ public:
|
||||
return mObservers.Length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call Notify() on each item in the list.
|
||||
* Handles the case of Notify() calling RemoveObserver()
|
||||
*/
|
||||
void Broadcast(const T& aParam)
|
||||
{
|
||||
nsTArray<Observer<T>*> observersCopy(mObservers);
|
||||
uint32_t size = observersCopy.Length();
|
||||
MOZ_ASSERT(mBroadcastCopy.IsEmpty());
|
||||
mBroadcastCopy = mObservers;
|
||||
uint32_t size = mBroadcastCopy.Length();
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
observersCopy[i]->Notify(aParam);
|
||||
// nulled if Removed during Broadcast
|
||||
if (mBroadcastCopy[i]) {
|
||||
mBroadcastCopy[i]->Notify(aParam);
|
||||
}
|
||||
}
|
||||
mBroadcastCopy.Clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsTArray<Observer<T>*> mObservers;
|
||||
nsTArray<Observer<T>*> mBroadcastCopy;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
Loading…
Reference in New Issue
Block a user