isl_archive.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,134 行 · 第 1/3 页
C
1,134 行
ISL_STATUS
AddOldCertificate(
ISL_ARCHIVE_CONTEXT_PTR Context,
ISL_CONST_DATA Name,
ISL_CERTIFICATE_METHODS *CertMethods,
ISL_CONST_DATA InMemoryImage)
{
ISL_CERTIFICATE_PTR CertPtr;
ISL_LIST_PTR CertListPtr;
Name;
CertPtr = isl_AllocateMemory(Context->Memory, sizeof(ISL_CERTIFICATE));
if (!CertPtr) {
return ISL_FAIL;
}
if (ISL_OK != CertMethods->Initialize(
CertPtr,
Context->Memory,
InMemoryImage) )
{
return ISL_FAIL;
}
CertListPtr = isl_AllocateMemory(Context->Memory, sizeof(ISL_LIST));
if (!CertListPtr) {
return ISL_FAIL;
}
CertListPtr->Node = CertPtr;
CertListPtr->Next = Context->Certs;
#if 0
pCertList->Name.Data = isl_AllocateMemory(Context->Memory, Name.Length);
if (!pCertList->Name.Data){
return ISL_FAIL;
}
cssm_memcpy((void*)pCertList->Name.Data, (void*)Name.Data, Name.Length);
pCertList->Name.Length = Name.Length;
#endif
Context->Certs = CertListPtr;
return ISL_OK;
}
/*-----------------------------------------------------------------------------
* Class: Archive
* Name: InitializeFromMemory
*
* Description:
* Constructor for existing in-memory archive
*
* Parameters:
* Context (input/output) : this pointer
* configContext (input) : algorithm<->code extension
* InMemoryImage (input) : memory image of external representation
*
* Return value:
* status of operation
*
* Error Codes:
*
* Notes:
* InMemoryImage is assumed to be persistent for the life of the archive object
*---------------------------------------------------------------------------*/
static
ISL_STATUS
InitializeFromMemory(
ISL_ARCHIVE_CONTEXT *Context,
ISL_CONFIG_PTR Config,
ISL_CONST_DATA InMemoryImage)
{
PK_ARCHIVE_PTR pPKArchive;
PK_ITERATOR_PTR pkIterator;
ISL_CONST_DATA Filename;
ISL_CONST_DATA Filedata;
ISL_CONST_DATA FilePath;
ISL_MEMORY_CONTEXT_PTR MemoryPtr;
if (Context == NULL || Config == NULL)
return ISL_FAIL;
cssm_memset(Context, 0, sizeof(ISL_ARCHIVE_CONTEXT));
Context->Config = Config;
// Context->Methods = &ArchiveMethods;
/* Allocate the Archive's ISL_MEMORY_CONTEXT */
MemoryPtr = Config->MemoryMethods->calloc_func(
sizeof(ISL_MEMORY_CONTEXT),
1,
Config->AllocRef);
if (MemoryPtr == NULL) return ISL_FAIL;
MemoryPtr->MemoryMethods = Config->MemoryMethods;
MemoryPtr->AllocRef = Config->AllocRef;
Context->Memory = MemoryPtr;
/* Parse the Archive Components */
pPKArchive = pk_InitializeFromMemory(Context->Memory, InMemoryImage);
if (pPKArchive == NULL) {
return ISL_FAIL;
}
Filename.Data = (const uint8 *)"META-INF/MANIFEST.MF";
Filename.Length = 20;
if (ISL_OK != pk_FindFile(pPKArchive, Filename, &Filedata))
{
return ISL_FAIL;
}
/* parse the manifest file */
Context->Manifest.Image.Data = Filedata.Data;
Context->Manifest.Image.Length = Filedata.Length;
if (ISL_OK != isl_BuildManifest(Context))
{
return ISL_FAIL;
}
pkIterator = pk_CreateFileEnumerator(pPKArchive);
if (pkIterator == NULL) {
return ISL_FAIL;
}
while (ISL_OK == pk_GetNextFile(pkIterator, &FilePath, &Filedata))
{
ISL_CONST_DATA FileName;
ISL_CONST_DATA FileTitle;
ISL_CONST_DATA FileExt;
ISL_SERVICE_CLASS_METHODS* ServiceMethods;
ISL_SERVICE_CLASS ServiceClass;
ISL_CONST_DATA ServiceName;
ISL_CONST_DATA AlgId;
if (ISL_OK != isl_ParseFilePath(FilePath, NULL, &FileName, &FileTitle, &FileExt))
{
goto FAIL;
}
ServiceMethods = ArchiveConfigMethods.FindAlgorithm(Config, FileExt);
if (ServiceMethods == NULL) {
continue;
}
ServiceMethods->id(&ServiceClass, &AlgId, &ServiceName);
switch (ServiceClass) {
case ISL_ServiceParseSignature:
if (ISL_OK != AddOldSignature(
Context,
FileTitle,
(ISL_SIGNATURE_METHODS *)ServiceMethods,
Filedata))
{
return ISL_FAIL;
}
break;
case ISL_ServiceParseCertificate:
if (ISL_OK != AddOldCertificate(
Context,
FileTitle,
(ISL_CERTIFICATE_METHODS *)ServiceMethods,
Filedata))
{
return ISL_FAIL;
}
break;
default:
continue;
}
}
(void)pk_RecycleFileEnumerator(pkIterator);
return ISL_OK;
FAIL:
(void)pk_RecycleFileEnumerator(pkIterator);
return ISL_FAIL;
}
/*-----------------------------------------------------------------------------
* Name: isl_RecycleArchiveContext
*
* Description:
* This function will free all the resources allocate by itself and all
* subordinate objects
*
* Parameters:
* Context (input)
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
static
ISL_STATUS
isl_RecycleArchiveContext(
ISL_ARCHIVE_CONTEXT *Context)
{
if (Context == NULL ||
Context->Memory == NULL)
{
return ISL_FAIL;
}
/* Recycle Signature Certificate Objects */
isl_RecycleMemoryContext(Context->Memory);
Context->Memory->MemoryMethods->free_func(Context->Memory, Context->Memory->AllocRef);
cssm_memset(Context, 0, sizeof(ISL_ARCHIVE_CONTEXT)); /* zero out memory */
return ISL_OK;
}
/*-----------------------------------------------------------------------------
* Name: FindSignableObject
*
* Description:
* Finds a signable object in the archive
*
* Parameters:
* Context - the archive context
* Name - name of signable object to find
*
* Return value:
* ISL_MANIFEST_SECTION_PTR - if object found
* NULL - if object not found
*
* Error Codes:
*---------------------------------------------------------------------------*/
static ISL_MANIFEST_SECTION_PTR FindSignableObject(
ISL_ARCHIVE_CONTEXT *Context, /* context */
ISL_CONST_DATA Name) /* manifest section name */
{
ISL_LIST_PTR CurrNodePtr;
if (Context == NULL ||
Name.Data == NULL)
{
return NULL;
}
/* search through manifest list for the specified section. */
/* If found, delete it from the list */
for(CurrNodePtr = Context->Manifest.Section;
CurrNodePtr;
CurrNodePtr = CurrNodePtr->Next)
{
ISL_MANIFEST_SECTION_PTR ManSectPtr;
ManSectPtr = CurrNodePtr->Node;
if (IS_EQUAL(ManSectPtr->SectionInfo.Name, Name)) {
return ManSectPtr;
}
}
return NULL;
}
/*-----------------------------------------------------------------------------
* Name: isl_BuildManifest
*
* Description:
*
* Parameters:
* ArchivePtr (input)
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
ISL_STATUS
isl_BuildManifest(
ISL_ARCHIVE_CONTEXT_PTR ArchivePtr)
{
ISL_SECTION_INFO_GROUP SectionInfoGroup;
if (ArchivePtr == NULL) return ISL_FAIL;
if (isl_JarFileDecode(
ArchivePtr->Memory,
ArchivePtr->Manifest.Image,
&SectionInfoGroup) != ISL_OK)
{
return ISL_FAIL;
}
/* The first SectionInfo in the SectionInfoGroup corresponds to the
Manifest header and not any one manifest section */
if (SectionInfoGroup.NumberOfSections == 0) return ISL_FAIL;
/* Initialize Manifest Header */
{
ISL_HEADER_SECTION_PTR HeaderPtr;
HeaderPtr = &ArchivePtr->Manifest.Header;
if (ISL_OK != isl_BuildHeaderSection(
HeaderPtr,
ArchivePtr->Memory,
SectionInfoGroup.Sections))
return ISL_FAIL;
}
/* then process the Manifest Sections */
{
ISL_LIST_PTR ManifestSectionListPtr;
ISL_MANIFEST_SECTION_PTR ManifestSectionPtr;
uint32 i;
ArchivePtr->Manifest.SectionCount =
SectionInfoGroup.NumberOfSections -
1;
ArchivePtr->Manifest.Section = isl_AllocateMemory(
ArchivePtr->Memory,
ArchivePtr->Manifest.SectionCount*sizeof(ISL_LIST));
if (ArchivePtr->Manifest.Section == NULL) return ISL_FAIL;
ManifestSectionPtr = isl_AllocateMemory(
ArchivePtr->Memory,
ArchivePtr->Manifest.SectionCount*sizeof(ISL_MANIFEST_SECTION));
if (ManifestSectionPtr == NULL) return ISL_FAIL;
ManifestSectionListPtr = ArchivePtr->Manifest.Section;
for(i=1; i < SectionInfoGroup.NumberOfSections; i++)
{
ManifestSectionListPtr->Next = ManifestSectionListPtr + 1;
ManifestSectionListPtr->Node = ManifestSectionPtr;
ManifestSectionPtr->Parent = ArchivePtr;
if (isl_BuildManifestSection(
ManifestSectionPtr,
SectionInfoGroup.Sections + i) != ISL_OK)
return ISL_FAIL;
ManifestSectionPtr++;
ManifestSectionListPtr++;
}
(--ManifestSectionListPtr)->Next = NULL;
}
return ISL_OK;
}
/*-----------------------------------------------------------------------------
* Name: Verify
*
* Description:
* Verifies a signature in the context of the archive i.e. the signature's
* signed content is a signed object list. After verifying the integrity of the
* signed object list, the integrity of the referenced manifest sections is
* checked.
*
* Parameters:
* ArchivePtr (input)
* SignaturePtr (input)
* CertMethods (input)
* CertificatePtr (input)
*
* Return value:
*
* Error Codes:
*---------------------------------------------------------------------------*/
static
ISL_STATUS
Verify(
ISL_ARCHIVE_CONTEXT_PTR ArchivePtr,
ISL_SIGNATURE_CONTEXT_PTR SignaturePtr, /* archive context */
ISL_CERTIFICATE_METHODS *CertMethods, /* configuration methods for certificate format */
ISL_CERTIFICATE_PTR CertificatePtr) /* the certificate */
{
ISL_SIGNER_CONTEXT_PTR SignerPtr;
ISL_LIST_PTR Signatures;
ISL_SIGNATURE_INFO_PTR SigInfoPtr = NULL;
ISL_SIG_SECTION_GROUP_PTR SigObjGrpPtr = NULL;
for(Signatures = ArchivePtr->Signatures;
Signatures != NULL;
Signatures = Signatures->Next)
{
SigInfoPtr = Signatures->Node;
if (SigInfoPtr->SignaturePtr == SignaturePtr)
break;
}
if (SigInfoPtr == NULL) return ISL_FAIL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?