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 + -
显示快捷键?