bug 63451 - moved signature verification functions from nsIZipReader to nsIJAR. r=sgehani, sr=shaver

This commit is contained in:
mstoltz%netscape.com 2001-02-23 00:15:04 +00:00
Родитель 55ca642440
Коммит 6ddb173736
11 изменённых файлов: 82 добавлений и 81 удалений

Просмотреть файл

@ -56,6 +56,7 @@
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "nsIZipReader.h"
#include "nsIJAR.h"
#include "nsIPluginInstance.h"
#include "nsIXPConnect.h"
#include "nsIScriptGlobalObject.h"
@ -366,8 +367,6 @@ nsSecurityNameSet::AddNameSet(nsIScriptContext* aScriptContext)
return NS_OK;
}
/////////////////////////////
// nsScriptSecurityManager //
/////////////////////////////
@ -399,6 +398,10 @@ SetBit(unsigned char *bitVector, PRInt32 index)
// Methods implementing nsIScriptSecurityManager //
///////////////////////////////////////////////////
static char *domPropNames[] = {
NS_DOM_PROP_NAMES
};
NS_IMETHODIMP
nsScriptSecurityManager::CheckScriptAccess(JSContext *cx,
void *aObj, PRInt32 domPropInt,
@ -1292,15 +1295,16 @@ nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID,
#endif
systemCertFile->Append("systemSignature.jar");
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
nsCOMPtr<nsIZipReader> systemCertJar;
nsCOMPtr<nsIZipReader> systemCertZip;
rv = nsComponentManager::CreateInstance(kZipReaderCID, nsnull,
NS_GET_IID(nsIZipReader),
getter_AddRefs(systemCertJar));
getter_AddRefs(systemCertZip));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
systemCertJar->Init(systemCertFile);
rv = systemCertJar->Open();
systemCertZip->Init(systemCertFile);
rv = systemCertZip->Open();
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIJAR> systemCertJar = do_QueryInterface(systemCertZip);
rv = systemCertJar->GetCertificatePrincipal(nsnull,
getter_AddRefs(mSystemCertificate));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
@ -1672,12 +1676,6 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj,
/*
** Access tests failed, so now report error.
*/
char *str;
if (NS_FAILED(subject->ToUserVisibleString(&str)))
return NS_ERROR_FAILURE;
JS_ReportError(aCx, "access disallowed from scripts at %s to documents "
"at another domain", str);
nsCRT::free(str);
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
}
@ -1748,10 +1746,6 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext,
return NS_OK;
}
static char *domPropNames[] = {
NS_DOM_PROP_NAMES
};
struct nsDomainEntry {
nsDomainEntry(const char *anOrigin, const char *aPolicy,
int aPolicyLength)

Просмотреть файл

@ -1 +1,3 @@
nsIZipReader.idl
nsIJAR.idl

Просмотреть файл

@ -37,6 +37,7 @@ DLL=$(OBJDIR)\$(DLLNAME).dll
MAPFILE=$(DLLNAME).map
XPIDLSRCS=.\nsIZipReader.idl \
.\nsIJAR.idl \
$(NULL)
EXPORTS=zipfile.h

Просмотреть файл

@ -22,9 +22,10 @@
* Daniel Veditz <dveditz@netscape.com>
* Don Bragg <dbragg@netscape.com>
* Samir Gehani <sgehani@netscape.com>
* Mitch Stoltz <mstoltz@netscape.com>
*/
#include "nsIZip.idl"
#include "nsISupports.idl"
%{C++
#define NS_JAR_CID \
@ -55,20 +56,29 @@
}
%}
interface nsIPrincipal;
[uuid(04501DB2-0409-11d3-BCF8-00805F0E1353)]
interface nsIJAR : nsIZip
interface nsIJAR : nsISupports
{
/* This interface will be filled with other "JAR"-related functions. */
/* The term "JAR" is in reference to security as opposed to "Zip"
* which is a non-secure archive format. */
const short NOT_SIGNED = 0;
const short VALID = 1;
const short INVALID_SIG = 2;
const short INVALID_UNKNOWN_CA = 3;
const short INVALID_MANIFEST = 4;
const short INVALID_ENTRY = 5;
const short NO_MANIFEST = 6;
/**
* Returns an object describing the entity which signed
* an entry. parseManifest must be called first. If aEntryName is an
* entry in the jar, getInputStream must be called after parseManifest.
* If aEntryName is an external file which has meta-information
* stored in the jar, verifyExternalFile (not yet implemented) must
* be called before getPrincipal.
*/
void getCertificatePrincipal(in string aEntryName, out nsIPrincipal aPrincipal);
};
[uuid(70993CAD-2922-11d3-A431-0060B0EB5963)]
interface nsIJARItem : nsISupports
{
readonly attribute string name;
readonly attribute PRUint16 compression;
readonly attribute PRUint32 size;
readonly attribute PRUint32 realsize;
readonly attribute PRUint32 crc32;
};

Просмотреть файл

@ -29,7 +29,6 @@
interface nsISimpleEnumerator;
interface nsIInputStream;
interface nsIPrincipal;
interface nsIFile;
[scriptable, uuid(6ca5e43e-9632-11d3-8cd9-0060b0fc14a3)]
@ -45,15 +44,6 @@ interface nsIZipEntry : nsISupports
[scriptable, uuid(6ff6a966-9632-11d3-8cd9-0060b0fc14a3)]
interface nsIZipReader : nsISupports
{
const short NOT_SIGNED = 0;
const short VALID = 1;
const short INVALID_SIG = 2;
const short INVALID_UNKNOWN_CA = 3;
const short INVALID_MANIFEST = 4;
const short INVALID_ENTRY = 5;
const short NO_MANIFEST = 6;
/**
* Initializes a zip reader after construction.
*/
@ -99,17 +89,6 @@ interface nsIZipReader : nsISupports
* Returns an input stream containing the contents of the specified zip entry.
*/
nsIInputStream getInputStream(in string zipEntry);
/**
* Returns an object describing the entity which signed
* an entry. parseManifest must be called first. If aEntryName is an
* entry in the jar, getInputStream must be called after parseManifest.
* If aEntryName is an external file which has meta-information
* stored in the jar, verifyExternalFile (not yet implemented) must
* be called before getPrincipal.
*/
void getCertificatePrincipal(in string aEntryName, out nsIPrincipal aPrincipal);
};
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -32,6 +32,7 @@
#include "nsIServiceManager.h"
#include "plbase64.h"
#include "nsIConsoleService.h"
#include "nscore.h"
#ifdef XP_UNIX
#include <sys/stat.h>
@ -121,7 +122,7 @@ public:
//-------------------------------------------------
nsJARManifestItem::nsJARManifestItem(): mType(JAR_INTERNAL),
entryVerified(PR_FALSE),
status(nsIZipReader::NOT_SIGNED),
status(nsIJAR::NOT_SIGNED),
calculatedSectionDigest(nsnull),
storedEntryDigest(nsnull)
{
@ -147,7 +148,7 @@ DeleteManifestEntry(nsHashKey* aKey, void* aData, void* closure)
// The following initialization makes a guess of 10 entries per jarfile.
nsJAR::nsJAR(): mManifestData(nsnull, nsnull, DeleteManifestEntry, nsnull, 10),
mParsedManifest(PR_FALSE), mGlobalStatus(nsIZipReader::NOT_SIGNED),
mParsedManifest(PR_FALSE), mGlobalStatus(nsIJAR::NOT_SIGNED),
mReleaseTime(PR_INTERVAL_NO_TIMEOUT), mCache(nsnull), mLock(nsnull)
{
NS_INIT_REFCNT();
@ -160,7 +161,7 @@ nsJAR::~nsJAR()
PR_DestroyLock(mLock);
}
NS_IMPL_THREADSAFE_QUERY_INTERFACE1(nsJAR, nsIZipReader)
NS_IMPL_THREADSAFE_QUERY_INTERFACE2(nsJAR, nsIZipReader, nsIJAR)
NS_IMPL_THREADSAFE_ADDREF(nsJAR)
// Custom Release method works with nsZipReaderCache...
@ -185,7 +186,7 @@ nsrefcnt nsJAR::Release(void)
}
//----------------------------------------------
// nsJAR public implementation
// nsIZipReader implementation
//----------------------------------------------
NS_METHOD
@ -341,6 +342,10 @@ nsJAR::GetInputStream(const char* aFilename, nsIInputStream** result)
return NS_OK;
}
//----------------------------------------------
// nsIJAR implementation
//----------------------------------------------
NS_IMETHODIMP
nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
{
@ -358,7 +363,7 @@ nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
//-- Parse the manifest
rv = ParseManifest(verifier);
if (NS_FAILED(rv)) return rv;
if (mGlobalStatus == nsIZipReader::NO_MANIFEST)
if (mGlobalStatus == nsIJAR::NO_MANIFEST)
return NS_OK;
PRInt16 requestedStatus;
@ -366,7 +371,7 @@ nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
{
//-- Find the item
nsCStringKey key(aFilename);
nsJARManifestItem* manItem = (nsJARManifestItem*)mManifestData.Get(&key);
nsJARManifestItem* manItem = NS_STATIC_CAST(nsJARManifestItem*, mManifestData.Get(&key));
if (!manItem)
return NS_OK;
//-- Verify the item against the manifest
@ -384,7 +389,7 @@ nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
else // User wants identity of signer w/o verifying any entries
requestedStatus = mGlobalStatus;
if (requestedStatus != nsIZipReader::VALID)
if (requestedStatus != nsIJAR::VALID)
ReportError(aFilename, requestedStatus);
else // Valid signature
{
@ -481,7 +486,7 @@ nsJAR::ParseManifest(nsISignatureVerifier* verifier)
if (NS_FAILED(rv)) return rv;
if (!file)
{
mGlobalStatus = nsIZipReader::NO_MANIFEST;
mGlobalStatus = nsIJAR::NO_MANIFEST;
mParsedManifest = PR_TRUE;
return NS_OK;
}
@ -514,7 +519,7 @@ nsJAR::ParseManifest(nsISignatureVerifier* verifier)
if (NS_FAILED(rv)) return rv;
if (!file)
{
mGlobalStatus = nsIZipReader::NO_MANIFEST;
mGlobalStatus = nsIJAR::NO_MANIFEST;
mParsedManifest = PR_TRUE;
return NS_OK;
}
@ -543,7 +548,7 @@ nsJAR::ParseManifest(nsISignatureVerifier* verifier)
}
if (NS_FAILED(rv))
{
mGlobalStatus = nsIZipReader::NO_MANIFEST;
mGlobalStatus = nsIJAR::NO_MANIFEST;
mParsedManifest = PR_TRUE;
return NS_OK;
}
@ -554,11 +559,11 @@ nsJAR::ParseManifest(nsISignatureVerifier* verifier)
&verifyError, getter_AddRefs(mPrincipal));
if (NS_FAILED(rv)) return rv;
if (mPrincipal)
mGlobalStatus = nsIZipReader::VALID;
mGlobalStatus = nsIJAR::VALID;
else if (verifyError == nsISignatureVerifier::VERIFY_ERROR_UNKNOWN_CA)
mGlobalStatus = nsIZipReader::INVALID_UNKNOWN_CA;
mGlobalStatus = nsIJAR::INVALID_UNKNOWN_CA;
else
mGlobalStatus = nsIZipReader::INVALID_SIG;
mGlobalStatus = nsIJAR::INVALID_SIG;
//-- Parse the SF file. If the verification above failed, principal
// is null, and ParseOneFile will mark the relevant entries as invalid.
@ -665,14 +670,14 @@ nsJAR::ParseOneFile(nsISignatureVerifier* verifier,
NS_ASSERTION(curItemSF->status == nsJAR::NOT_SIGNED,
"SECURITY ERROR: nsJARManifestItem not correctly initialized");
curItemSF->status = mGlobalStatus;
if (curItemSF->status == nsIZipReader::VALID)
if (curItemSF->status == nsIJAR::VALID)
{ // Compare digests
if (storedSectionDigest.Length() == 0)
curItemSF->status = nsIZipReader::NOT_SIGNED;
curItemSF->status = nsIJAR::NOT_SIGNED;
else
{
if (!storedSectionDigest.Equals((const char*)curItemSF->calculatedSectionDigest))
curItemSF->status = nsIZipReader::INVALID_MANIFEST;
curItemSF->status = nsIJAR::INVALID_MANIFEST;
JAR_NULLFREE(curItemSF->calculatedSectionDigest)
storedSectionDigest = "";
}
@ -754,18 +759,18 @@ nsJAR::VerifyEntry(nsISignatureVerifier* verifier,
nsJARManifestItem* aManItem, const char* aEntryData,
PRUint32 aLen)
{
if (aManItem->status == nsIZipReader::VALID)
if (aManItem->status == nsIJAR::VALID)
{
if(!aManItem->storedEntryDigest)
// No entry digests in manifest file. Entry is unsigned.
aManItem->status = nsIZipReader::NOT_SIGNED;
aManItem->status = nsIJAR::NOT_SIGNED;
else
{ //-- Calculate and compare digests
char* calculatedEntryDigest;
nsresult rv = CalculateDigest(verifier, aEntryData, aLen, &calculatedEntryDigest);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
if (PL_strcmp(aManItem->storedEntryDigest, calculatedEntryDigest) != 0)
aManItem->status = nsIZipReader::INVALID_ENTRY;
aManItem->status = nsIJAR::INVALID_ENTRY;
JAR_NULLFREE(calculatedEntryDigest)
JAR_NULLFREE(aManItem->storedEntryDigest)
}
@ -786,19 +791,19 @@ void nsJAR::ReportError(const char* aFilename, PRInt16 errorCode)
message.AppendWithConversion(" is invalid because ");
switch(errorCode)
{
case nsIZipReader::NOT_SIGNED:
case nsIJAR::NOT_SIGNED:
message.AppendWithConversion("the archive did not contain a valid PKCS7 signature.");
break;
case nsIZipReader::INVALID_SIG:
case nsIJAR::INVALID_SIG:
message.AppendWithConversion("the digital signature (*.RSA) file is not a valid signature of the signature instruction file (*.SF).");
break;
case nsIZipReader::INVALID_UNKNOWN_CA:
case nsIJAR::INVALID_UNKNOWN_CA:
message.AppendWithConversion("the certificate used to sign this file has an unrecognized issuer.");
break;
case nsIZipReader::INVALID_MANIFEST:
case nsIJAR::INVALID_MANIFEST:
message.AppendWithConversion("the signature instruction file (*.SF) does not contain a valid hash of the MANIFEST.MF file.");
break;
case nsIZipReader::INVALID_ENTRY:
case nsIJAR::INVALID_ENTRY:
message.AppendWithConversion("the MANIFEST.MF file does not contain a valid hash of the file being verified.");
break;
default:
@ -1198,7 +1203,7 @@ nsZipReaderCache::GetZip(nsIFile* zipFile, nsIZipReader* *result)
if (NS_FAILED(rv)) return rv;
nsCStringKey key(path);
nsJAR* zip = (nsJAR*)mZips.Get(&key); // AddRefs
nsJAR* zip = NS_STATIC_CAST(nsJAR*, NS_STATIC_CAST(nsIZipReader*,mZips.Get(&key))); // AddRefs
if (zip) {
#ifdef ZIP_CACHE_HIT_RATE
mZipCacheHits++;
@ -1223,7 +1228,7 @@ nsZipReaderCache::GetZip(nsIFile* zipFile, nsIZipReader* *result)
return rv;
}
PRBool collision = mZips.Put(&key, zip); // AddRefs to 2
PRBool collision = mZips.Put(&key, NS_STATIC_CAST(nsIZipReader*, zip)); // AddRefs to 2
NS_ASSERTION(!collision, "horked");
}
*result = zip;

Просмотреть файл

@ -50,6 +50,7 @@
#include "nsHashtable.h"
#include "nsAutoLock.h"
#include "nsIZipReader.h"
#include "nsIJAR.h"
#include "nsZipArchive.h"
#include "zipfile.h"
#include "nsIPrincipal.h"
@ -66,7 +67,7 @@ class nsZipReaderCache;
* nsJAR serves as an XPCOM wrapper for nsZipArchive with the addition of
* JAR manifest file parsing.
*------------------------------------------------------------------------*/
class nsJAR : public nsIZipReader
class nsJAR : public nsIZipReader, public nsIJAR
{
// Allows nsJARInputStream to call the verification functions
friend class nsJARInputStream;
@ -82,6 +83,8 @@ class nsJAR : public nsIZipReader
NS_DECL_NSIZIPREADER
NS_DECL_NSIJAR
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsIAggregatePrincipal.h"
#include "nsIProgressEventSink.h"
#include "nsXPIDLString.h"
#include "nsIJAR.h"
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
@ -495,8 +496,10 @@ nsJARChannel::GetOwner(nsISupports* *aOwner)
rv = EnsureZipReader();
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIJAR> jar = do_QueryInterface(mJAR, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Zip reader is not an nsIJAR");
nsCOMPtr<nsIPrincipal> certificate;
rv = mJAR->GetCertificatePrincipal(mJAREntry,
rv = jar->GetCertificatePrincipal(mJAREntry,
getter_AddRefs(certificate));
if (NS_FAILED(rv)) return rv;
if (certificate)

Просмотреть файл

@ -138,7 +138,7 @@ public:
*
* @param aFilename Name of file in the archive
* @return status code
*/
*/
PRInt32 GetItem(const char * aFilename, nsZipItem** result);
/**

Просмотреть файл

@ -34,6 +34,7 @@ MODULES_LIBJAR_LEXPORTS = \
MODULES_LIBJAR_LXPIDLSRCS = \
nsIZipReader.idl \
nsIJAR.idl \
$(NULL)
MODULES_LIBJAR_CPPSRCS := $(addprefix $(topsrcdir)/modules/libjar/, $(MODULES_LIBJAR_LCPPSRCS))

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsIAggregatePrincipal.h"
#include "nsIProgressEventSink.h"
#include "nsXPIDLString.h"
#include "nsIJAR.h"
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
@ -495,8 +496,10 @@ nsJARChannel::GetOwner(nsISupports* *aOwner)
rv = EnsureZipReader();
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIJAR> jar = do_QueryInterface(mJAR, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Zip reader is not an nsIJAR");
nsCOMPtr<nsIPrincipal> certificate;
rv = mJAR->GetCertificatePrincipal(mJAREntry,
rv = jar->GetCertificatePrincipal(mJAREntry,
getter_AddRefs(certificate));
if (NS_FAILED(rv)) return rv;
if (certificate)