2015-09-07 11:12:02 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_net_PackagedAppVerifier_h
|
|
|
|
#define mozilla_net_PackagedAppVerifier_h
|
|
|
|
|
|
|
|
#include "nsICacheEntry.h"
|
|
|
|
#include "nsIURI.h"
|
|
|
|
#include "nsClassHashtable.h"
|
|
|
|
#include "nsHashKeys.h"
|
|
|
|
#include "nsICryptoHash.h"
|
|
|
|
#include "nsIPackagedAppVerifier.h"
|
2015-09-21 01:11:00 +00:00
|
|
|
#include "mozilla/LinkedList.h"
|
2015-09-24 02:07:01 +00:00
|
|
|
#include "nsIPackagedAppUtils.h"
|
2015-09-07 11:12:02 +00:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace net {
|
|
|
|
|
|
|
|
class PackagedAppVerifier final
|
|
|
|
: public nsIPackagedAppVerifier
|
2015-09-24 02:07:01 +00:00
|
|
|
, public nsIVerificationCallback
|
2015-09-07 11:12:02 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
|
|
NS_DECL_NSISTREAMLISTENER
|
|
|
|
NS_DECL_NSIPACKAGEDAPPVERIFIER
|
2015-09-24 02:07:01 +00:00
|
|
|
NS_DECL_NSIVERIFICATIONCALLBACK
|
2015-09-07 11:12:02 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
enum EState {
|
|
|
|
// The initial state.
|
|
|
|
STATE_UNKNOWN,
|
|
|
|
|
2015-09-21 01:11:00 +00:00
|
|
|
// When we are notified to process the first resource, we will start to
|
|
|
|
// verify the manifest and go to this state no matter the package has
|
|
|
|
// signature or not.
|
|
|
|
STATE_MANIFEST_VERIFYING,
|
|
|
|
|
2015-09-07 11:12:02 +00:00
|
|
|
// Either the package has no signature or the manifest is verified
|
|
|
|
// successfully will we be in this state.
|
|
|
|
STATE_MANIFEST_VERIFIED_OK,
|
|
|
|
|
|
|
|
// iff the package has signature but the manifest is not well signed.
|
|
|
|
STATE_MANIFEST_VERIFIED_FAILED,
|
|
|
|
|
|
|
|
// The manifest is well signed but the resource integrity check failed.
|
|
|
|
STATE_RESOURCE_VERIFIED_FAILED,
|
|
|
|
};
|
|
|
|
|
|
|
|
// The only reason to inherit from nsISupports is it needs to be
|
|
|
|
// passed as the context to PackagedAppVerifier::OnStopRequest.
|
|
|
|
class ResourceCacheInfo : public nsISupports
|
2015-09-21 01:11:00 +00:00
|
|
|
, public mozilla::LinkedListElement<ResourceCacheInfo>
|
2015-09-07 11:12:02 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
ResourceCacheInfo(nsIURI* aURI,
|
|
|
|
nsICacheEntry* aCacheEntry,
|
|
|
|
nsresult aStatusCode,
|
|
|
|
bool aIsLastPart)
|
|
|
|
: mURI(aURI)
|
|
|
|
, mCacheEntry(aCacheEntry)
|
|
|
|
, mStatusCode(aStatusCode)
|
|
|
|
, mIsLastPart(aIsLastPart)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-09-21 01:11:00 +00:00
|
|
|
ResourceCacheInfo(const ResourceCacheInfo& aCopyFrom)
|
|
|
|
: mURI(aCopyFrom.mURI)
|
|
|
|
, mCacheEntry(aCopyFrom.mCacheEntry)
|
|
|
|
, mStatusCode(aCopyFrom.mStatusCode)
|
|
|
|
, mIsLastPart(aCopyFrom.mIsLastPart)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// A ResourceCacheInfo must have a URI. If mURI is null, this
|
|
|
|
// resource is broken.
|
2015-09-07 11:12:02 +00:00
|
|
|
nsCOMPtr<nsIURI> mURI;
|
|
|
|
nsCOMPtr<nsICacheEntry> mCacheEntry;
|
|
|
|
nsresult mStatusCode;
|
|
|
|
bool mIsLastPart;
|
|
|
|
|
|
|
|
private:
|
|
|
|
virtual ~ResourceCacheInfo() { }
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
PackagedAppVerifier();
|
|
|
|
|
|
|
|
PackagedAppVerifier(nsIPackagedAppVerifierListener* aListener,
|
2015-10-22 09:09:44 +00:00
|
|
|
const nsACString& aPackageOrigin,
|
2015-09-07 11:12:02 +00:00
|
|
|
const nsACString& aSignature,
|
|
|
|
nsICacheEntry* aPackageCacheEntry);
|
|
|
|
|
2015-09-21 01:11:00 +00:00
|
|
|
// A internal used function to let the verifier know there's a broken
|
|
|
|
// last part.
|
|
|
|
void SetHasBrokenLastPart(nsresult aStatusCode);
|
|
|
|
|
|
|
|
// Used to explicitly clear the listener to avoid circula reference.
|
|
|
|
void ClearListener() { mListener = nullptr; }
|
|
|
|
|
2015-10-02 12:25:22 +00:00
|
|
|
bool GetIsPackageSigned() const
|
|
|
|
{
|
|
|
|
return mIsPackageSigned;
|
|
|
|
}
|
|
|
|
|
2015-10-19 01:33:00 +00:00
|
|
|
const nsACString& GetPackageIdentifier() const
|
2015-10-02 12:25:22 +00:00
|
|
|
{
|
2015-10-19 01:33:00 +00:00
|
|
|
return mPackageIdentifer;
|
2015-10-02 12:25:22 +00:00
|
|
|
}
|
|
|
|
|
2015-10-12 07:38:41 +00:00
|
|
|
bool WouldVerify() const;
|
|
|
|
|
2015-10-19 01:33:00 +00:00
|
|
|
static const char* kSignedPakIdMetadataKey;
|
2015-09-07 11:12:02 +00:00
|
|
|
|
|
|
|
private:
|
2015-09-21 01:11:00 +00:00
|
|
|
virtual ~PackagedAppVerifier();
|
2015-09-07 11:12:02 +00:00
|
|
|
|
|
|
|
// Called when a resource is already fully written in the cache. This resource
|
|
|
|
// will be processed and is guaranteed to be called back in either:
|
|
|
|
//
|
|
|
|
// 1) PackagedAppVerifierListener::OnManifestVerified:
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// If the resource is the first one in the package, it will be called
|
|
|
|
// back in OnManifestVerified no matter this package has a signature or not.
|
|
|
|
//
|
|
|
|
// 2) PackagedAppVerifierListener::OnResourceVerified.
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Otherwise, the resource will be called back here.
|
|
|
|
//
|
|
|
|
void ProcessResourceCache(const ResourceCacheInfo* aInfo);
|
|
|
|
|
2015-09-24 02:07:01 +00:00
|
|
|
// Callback for nsIInputStream::ReadSegment() to read manifest
|
|
|
|
static NS_METHOD WriteManifest(nsIInputStream* aStream,
|
|
|
|
void* aManifest,
|
|
|
|
const char* aFromRawSegment,
|
|
|
|
uint32_t aToOffset,
|
|
|
|
uint32_t aCount,
|
|
|
|
uint32_t* aWriteCount);
|
|
|
|
|
2015-09-07 11:12:02 +00:00
|
|
|
// This two functions would call the actual verifier.
|
|
|
|
void VerifyManifest(const ResourceCacheInfo* aInfo);
|
|
|
|
void VerifyResource(const ResourceCacheInfo* aInfo);
|
|
|
|
|
2015-09-21 01:11:00 +00:00
|
|
|
void OnManifestVerified(bool aSuccess);
|
|
|
|
void OnResourceVerified(bool aSuccess);
|
|
|
|
|
2015-09-07 11:12:02 +00:00
|
|
|
// To notify that either manifest or resource check is done.
|
|
|
|
nsCOMPtr<nsIPackagedAppVerifierListener> mListener;
|
|
|
|
|
|
|
|
// The internal verification state.
|
|
|
|
EState mState;
|
|
|
|
|
|
|
|
// Initialized as a normal origin. Will be updated once we verified the manifest.
|
|
|
|
nsCString mPackageOrigin;
|
|
|
|
|
|
|
|
// The signature of the package.
|
|
|
|
nsCString mSignature;
|
|
|
|
|
2015-09-24 02:07:01 +00:00
|
|
|
// The app manfiest of the package
|
|
|
|
nsCString mManifest;
|
|
|
|
|
|
|
|
// Whether we're processing the first resource, which is the manfiest
|
|
|
|
bool mIsFirstResource;
|
|
|
|
|
2015-09-07 11:12:02 +00:00
|
|
|
// Whether this package app is signed.
|
|
|
|
bool mIsPackageSigned;
|
|
|
|
|
2015-10-22 09:09:44 +00:00
|
|
|
// Whether we should bypass verification.
|
|
|
|
bool mBypassVerification;
|
|
|
|
|
2015-09-07 11:12:02 +00:00
|
|
|
// The package cache entry (e.g. http://foo.com/app.pak) used to store
|
|
|
|
// any necessarry signed package information.
|
|
|
|
nsCOMPtr<nsICacheEntry> mPackageCacheEntry;
|
|
|
|
|
|
|
|
// The resource URI that we are computing its hash.
|
|
|
|
nsCString mHashingResourceURI;
|
|
|
|
|
|
|
|
// Used to compute resource's hash value.
|
|
|
|
nsCOMPtr<nsICryptoHash> mHasher;
|
|
|
|
|
|
|
|
// The last computed hash value for a resource. It will be set on every
|
|
|
|
// |EndResourceHash| call.
|
|
|
|
nsCString mLastComputedResourceHash;
|
2015-09-21 01:11:00 +00:00
|
|
|
|
2015-09-24 02:07:01 +00:00
|
|
|
// This will help to verify manifests and resource integrity
|
|
|
|
nsCOMPtr<nsIPackagedAppUtils> mPackagedAppUtils;
|
|
|
|
|
2015-09-21 01:11:00 +00:00
|
|
|
// A list of pending resource that is downloaded but not verified yet.
|
|
|
|
mozilla::LinkedList<ResourceCacheInfo> mPendingResourceCacheInfoList;
|
|
|
|
|
|
|
|
// A place to store the computed hashes of each resource.
|
|
|
|
nsClassHashtable<nsCStringHashKey, nsCString> mResourceHashStore;
|
2015-10-19 01:33:00 +00:00
|
|
|
|
|
|
|
nsCString mPackageIdentifer;
|
2015-09-07 11:12:02 +00:00
|
|
|
}; // class PackagedAppVerifier
|
|
|
|
|
|
|
|
} // namespace net
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_net_PackagedAppVerifier_h
|