/*----------------------------------------------------------------------- * File: MAF_INTEG.C * * Copyright (c) 1995-2000 Intel Corporation. All rights reserved. *----------------------------------------------------------------------- */ /* * OpenVMS History * * 13-Sep-2002 Carol Kelly * o Merge in V3_14 changes * 20-Jun-2002 Wayne Morrison * o Fix information message when built against newer compiler * (comparison of NumCerts [unsigned] to a negative number). * */ #include "maf_include.h" #include "mds.h" #include "mds_schema.h" #ifdef ISL_INCLUDED #include "callouts.h" /* Maximum length of name/key buffers */ #define MAX_ISSUER_INFO_BUFFER 1024 #define MAX_CERTS 8 #ifdef VMS #include "rootkeys.h" #include "rootnames.h" #include "modselfkey.h" #else #include "intel/rootkeys.h" #include "intel/rootnames.h" #include "intel/modselfkey.h" #endif #endif /* ifdef ISL_INCLUDED */ /* Macro to include single lines of code in debug mode only */ #ifdef _DEBUG # define DEBUG_EXEC( line ) line #else # define DEBUG_EXEC( line ) #endif /* Debug magic number value */ #define MAF_ICI_MAGIC_NUMBER (0x19990726) #ifdef _DEBUG #define ASSERT_VALID_MICI_PTR( ptr ) assert( ptr && ((MAF_INTEG_CRED_INFO*)ptr)->MagicNumber == MAF_ICI_MAGIC_NUMBER ) #else #define ASSERT_VALID_MICI_PTR( ptr ) #endif /* Structure to hold miscellaneous credential information about a module. * The value of an ADDIN_MODULE_HANDLE is the pointer to one of these * structures. */ typedef struct _maf_integ_cred_info { #ifdef _DEBUG uint32 MagicNumber; #endif CSSM_GUID ModuleId; CSSM_KEY_HIERARCHY KeyHierarchy; MAF_INTEG_MODULE_TYPE ModuleType; #ifdef ISL_INCLUDED ISL_VERIFIED_MODULE_PTR pModule; #else CSSM_LIB_HANDLE hModule; #endif } MAF_INTEG_CRED_INFO; /* List of credentials that have been verified in the system. These values * are cached to provide speed advantages. */ static MAF_LIST_COLLECTION s_Credentials; /* Initialization indicator to catch order of operations problems. Only * present in debug mode. */ #ifdef VMS DEBUG_EXEC( static CSSM_BOOL s_bIntegInitialized = CSSM_FALSE ) DEBUG_EXEC( static CSSM_BOOL s_bIntegInitializing = CSSM_FALSE ) #else DEBUG_EXEC( static CSSM_BOOL s_bIntegInitialized = CSSM_FALSE ); DEBUG_EXEC( static CSSM_BOOL s_bIntegInitializing = CSSM_FALSE ); #endif /* MAF_ITEM_TEARDOWN_FUNC function implementation to destroy cached * credential records when the integrity management is terminated. */ static int MLC_FASTCALL addin_DeleteCredentials( MAF_INTEG_CRED_INFO *pCredInfo /* void *pItem */ ) { ASSERT_VALID_MICI_PTR( pCredInfo ); #ifdef ISL_INCLUDED if ( pCredInfo->pModule ) { CSSM_LIB_HANDLE hLib; hLib = EISL_GetLibHandle( pCredInfo->pModule ); EISL_RecycleVerifiedModuleCredentials( pCredInfo->pModule ); port_FreeLibrary( hLib ); } #else /* Release the library in the OS */ port_FreeLibrary( pCredInfo->hModule ); #endif /* Deallocate memory */ memset( pCredInfo, 0, sizeof(MAF_INTEG_CRED_INFO) ); Addin_free( pCredInfo, NULL ); return 0; } /* MAF_FIND_FUNC function implementation to find an entry in the credential * cache with a certain GUID and key hierarchy. */ static int MLC_FASTCALL addin_FindCredInfoByGuidAndHierarchy( const MAF_INTEG_CRED_INFO *pCredInfo, /* void *pItem */ const MAF_INTEG_CRED_INFO *pKey /* void *pKey */ ) { assert( pCredInfo && pKey ); ASSERT_VALID_MICI_PTR( pCredInfo ); ASSERT_VALID_MICI_PTR( pKey ); return ( ( MAF_CompareGuids( pCredInfo->ModuleId, pKey->ModuleId ) && ( pCredInfo->KeyHierarchy == pKey->KeyHierarchy ) ) ? 0 : 1 ); } CSSM_RETURN Addin_IntegrityInit() { CSSM_RETURN rv = CSSM_OK; /* Do some quick sanity checking */ DEBUG_EXEC( assert( !s_bIntegInitialized ) ); DEBUG_EXEC( s_bIntegInitializing = CSSM_TRUE ); /* Initialize the MDS connection */ if ( ( rv = Addin_MDSInit() ) == CSSM_OK ) { /* Perform a self-check */ if ( ( rv = Addin_SelfCheck() ) == CSSM_OK ) { /* Initialize the credentials list */ if ( MLC_Init( &s_Credentials, (MLC_ITEM_TEARDOWN_FUNC)addin_DeleteCredentials ) != CSSM_OK ) { ERR( rv = CSSM_ERRCODE_INTERNAL_ERROR ); } else { DEBUG_EXEC( s_bIntegInitialized = CSSM_TRUE ); } } /* Terminate the MDS connection if self-check or list init failed */ if ( rv != CSSM_OK ) { Addin_MDSTerm(); } } DEBUG_EXEC( s_bIntegInitializing = CSSM_FALSE ); return rv; } CSSM_RETURN Addin_IntegrityTerm() { CSSM_RETURN rv = CSSM_OK; /* Do some quick sanity checking */ DEBUG_EXEC( assert( s_bIntegInitialized ) ); /* Terminate the credentials list and destroy the contents */ if ( MLC_Term( &s_Credentials ) != CSSM_OK ) { ERR( rv = CSSM_ERRCODE_INTERNAL_ERROR ); } Addin_MDSTerm(); DEBUG_EXEC( s_bIntegInitialized = CSSM_FALSE ); return rv; } CSSM_RETURN Addin_ReverifyModule( ADDIN_MODULE_HANDLE hModule ) { CSSM_RETURN rv = CSSM_OK; const MAF_INTEG_CRED_INFO *pCredInfo = (const MAF_INTEG_CRED_INFO*)hModule; ASSERT_VALID_MICI_PTR( pCredInfo ); #ifdef ISL_INCLUDED if ( !EISL_ContinueVerification( pCredInfo->pModule, 1 ) ) { ERR( rv = CSSMERR_CSSM_MODULE_MANIFEST_VERIFY_FAILED ); } #endif return rv; } #ifdef ISL_INCLUDED static void addin_FreeIslConstDataArray( uint32 NumItems, ISL_CONST_DATA_PTR Array ) { uint32 i; if ( Array ) { for ( i = 0; i < NumItems; i++ ) { if ( Array[i].Data ) { Addin_free( (uint8*)Array[i].Data, NULL ); } } Addin_free( Array, NULL ); } } static void addin_FreeRootKeysAndNames( uint32 NumItems, ISL_CONST_DATA_PTR pRootKeys, ISL_CONST_DATA_PTR pRootNames ) { addin_FreeIslConstDataArray( NumItems, pRootKeys ); addin_FreeIslConstDataArray( NumItems, pRootNames ); } static CSSM_RETURN addin_GetRootKeysAndNames( CSSM_KEY_HIERARCHY KeyHierarchy, ISL_CONST_DATA_PTR *ppRootKeys, ISL_CONST_DATA_PTR *ppRootNames, uint32 *pNumItems ) { CSSM_RETURN rv = CSSM_OK; uint32 NumKeys = 0; ISL_CONST_DATA_PTR pRootKeys = NULL; ISL_CONST_DATA_PTR pRootNames = NULL; uint32 i; /* If called with NULL for 1st param, then returns NumKeys and StartIndex*/ /* Subsequent calls, returns the key at the index specified by StartIndex*/ if( KeyHierarchy == CSSM_KEY_HIERARCHY_INTEG ) { NumKeys = cssm_GetIntegrityRootKeys( NULL ); } else if( KeyHierarchy == CSSM_KEY_HIERARCHY_EXPORT ) { NumKeys = cssm_GetExportRootKeys( NULL ); } else { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); assert( 0 ); } if ( rv == CSSM_OK ) { if ( NumKeys == 0) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); assert( 0 ); } else { pRootKeys = Addin_calloc( sizeof(ISL_CONST_DATA), NumKeys, NULL ); pRootNames = Addin_calloc( sizeof(ISL_CONST_DATA), NumKeys, NULL ); if ( !pRootNames || !pRootKeys ) { ERR( rv = CSSM_ERRCODE_MEMORY_ERROR ); } else { for( i = 0; i < NumKeys; i++ ) { pRootKeys[i].Length = MAX_ISSUER_INFO_BUFFER; pRootKeys[i].Data = Addin_calloc( MAX_ISSUER_INFO_BUFFER, 1, NULL ); if( pRootKeys[i].Data == NULL ) { ERR( rv = CSSM_ERRCODE_MEMORY_ERROR ); break; } pRootNames[i].Length = MAX_ISSUER_INFO_BUFFER; pRootNames[i].Data = Addin_calloc( MAX_ISSUER_INFO_BUFFER, 1, NULL ); if( pRootNames[i].Data == NULL ) { ERR( rv = CSSM_ERRCODE_MEMORY_ERROR ); break; } } /* for i = 0 to NumKeys-1 */ if ( rv == CSSM_OK ) { if( KeyHierarchy == CSSM_KEY_HIERARCHY_INTEG ) { cssm_GetIntegrityRootKeys( (ISL_CALLOUT_DATA*)pRootKeys ); cssm_GetIntegrityRootNames( (ISL_CALLOUT_DATA*)pRootNames ); } else if( KeyHierarchy == CSSM_KEY_HIERARCHY_EXPORT ) { cssm_GetExportRootKeys( (ISL_CALLOUT_DATA*)pRootKeys ); cssm_GetExportRootNames( (ISL_CALLOUT_DATA*)pRootNames ); } } } /* Buffers allocated */ if ( rv != CSSM_OK ) { /* Free the key buffers in an error case */ addin_FreeRootKeysAndNames( NumKeys, pRootKeys, pRootNames ); pRootNames = NULL; pRootKeys = NULL; } } /* NumKeys > 0 */ } /* Valid key hierarchy */ /* Set return values */ *pNumItems = NumKeys; *ppRootKeys = pRootKeys; *ppRootNames = pRootNames; return rv; } CSSM_RETURN addin_GetVerifiedModulePointer( const CSSM_GUID *pModuleId, MAF_INTEG_MODULE_TYPE ModuleType, ISL_VERIFIED_SIGNATURE_ROOT_PTR pVerifiedRoot, ISL_VERIFIED_MODULE_PTR *ppModulePtr ) { CSSM_RETURN rv = CSSM_OK; ISL_VERIFIED_MODULE_PTR pVerifiedModule = NULL; ISL_MANIFEST_SECTION_PTR pSection = NULL; ISL_ITERATOR_PTR pSecIter = NULL; uint8 RequiredAttributeValue[MAF_PRINTABLE_GUID_LENGTH]; uint8 SectionAttributeValue[2 * MAF_PRINTABLE_GUID_LENGTH]; ISL_CONST_DATA ReqAttrValue; ISL_CONST_DATA SecAttrValue; ISL_CONST_DATA SecAttrName; if ( ( pSecIter = EISL_CreateManifestSectionEnumerator( pVerifiedRoot ) ) == NULL ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } else { /* Build the section executable name */ MAF_GetPrintableGUID( pModuleId, (char*)RequiredAttributeValue ); ReqAttrValue.Length = strlen( (char*)RequiredAttributeValue ); ReqAttrValue.Data = (uint8*)RequiredAttributeValue; /* Build the section attribute name */ SecAttrName.Data = (uint8*)"CDSA_GUID"; SecAttrName.Length = strlen( (char*)SecAttrName.Data ); /* Find the section named concat("executable:",pModuleName) */ while ( ( pSection = EISL_GetNextManifestSection( pSecIter ) ) != NULL ) { SecAttrValue.Data = SectionAttributeValue; SecAttrValue.Length = sizeof(SectionAttributeValue); if ( EISL_FindManifestSectionAttribute( pSection, SecAttrName, &SecAttrValue ) == ISL_OK ) { if ( ( ReqAttrValue.Length == SecAttrValue.Length ) && !memcmp( ReqAttrValue.Data, SecAttrValue.Data, ReqAttrValue.Length ) ) { /* This is the correct section */ break; } } } /* Make sure we found the correct section */ if ( !pSection ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } else { if ( ModuleType != MAF_INTEG_MT_OTHER ) { /* Find the CDSA_MODULE attribute and make sure it * matches the required type. */ SecAttrName.Data = (uint8*)"CDSA_MODULE"; SecAttrName.Length = strlen( (char*)SecAttrName.Data ); SecAttrValue.Data = (uint8*)SectionAttributeValue; SecAttrValue.Length = sizeof(SectionAttributeValue); /* Set the correct required value */ if ( ModuleType == MAF_INTEG_MT_CSSM ) { ReqAttrValue.Data = (uint8*)"CSSM"; } else { ReqAttrValue.Data = (uint8*)"EMM"; } ReqAttrValue.Length = strlen( (char*)ReqAttrValue.Data ); if ( EISL_FindManifestSectionAttribute( pSection, SecAttrName, &SecAttrValue ) == ISL_OK ) { if ( ( SecAttrValue.Length != ReqAttrValue.Length ) || memcmp( ReqAttrValue.Data, SecAttrValue.Data, ReqAttrValue.Length ) ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } } else { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } } /* Load the appropriate module */ if ( rv == CSSM_OK ) { pVerifiedModule = EISL_VerifyAndLoadModule( pSection ); if ( !pVerifiedModule ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } } } /* Delete the section iterator */ EISL_RecycleManifestSectionEnumerator( pSecIter ); } /* EISL_CreateManifestSectionEnumerator */ /* Set return parameters */ *ppModulePtr = pVerifiedModule; return rv; } static CSSM_RETURN addin_VerifyCredentials( ISL_CONST_DATA Credentials, ISL_CONST_DATA CredentialSearchPath, CSSM_KEY_HIERARCHY KeyHierarchy, ISL_VERIFIED_SIGNATURE_ROOT_PTR* pVerifiedRoot ) { CSSM_RETURN rv = CSSM_OK; ISL_VERIFIED_SIGNATURE_ROOT_PTR SigRoot = NULL; ISL_VERIFIED_CERTIFICATE_PTR SigCert = NULL; uint32 NumCerts = 0; uint32 NumKeys=0; uint32 i; ISL_CONST_DATA_PTR RootKeys = NULL; ISL_CONST_DATA_PTR RootNames = NULL; ISL_VERIFIED_CERTIFICATE_CHAIN_PTR CertChain = NULL; ISL_VERIFIED_CERTIFICATE_PTR Certs[MAX_CERTS]; if ( ( rv = addin_GetRootKeysAndNames( KeyHierarchy, &RootKeys, &RootNames, &NumKeys ) ) == CSSM_OK ) { /* Attempt to build a verified cert chain from one of the roots */ for( i = 0; i < NumKeys; i++ ) { CertChain = EISL_CreateCertificateChainWithCredentialData( RootNames[i], RootKeys[i], Credentials, CredentialSearchPath ); if ( CertChain != NULL ) { break; } } if ( CertChain == NULL ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } else { /* Find the leaf cert by copying the chain and fetching the last * cert. We don't have to free the "copied" chain because it is * referenced by the first cert chain. */ NumCerts = EISL_CopyCertificateChain( CertChain, Certs, MAX_CERTS ); if ( NumCerts == 0 ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } else { /* The signer cert if the last in the list */ SigCert = Certs[NumCerts - 1]; /* Create the signature root */ SigRoot = EISL_CreateVerifiedSignatureRootWithCredentialDataAndCertificate( Credentials, CredentialSearchPath, SigCert ); if ( SigRoot == NULL ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } } /* EISL_CopyCertificateChain */ /* Delete the certificate chain */ EISL_RecycleVerifiedCertificateChain( CertChain ); } /* EISL_CreateCertificateChain... */ addin_FreeRootKeysAndNames( NumKeys, RootKeys, RootNames ); } /* Addin_GetRootKeysAndNames */ /* Set the return values */ *pVerifiedRoot = SigRoot; return rv; } #endif /* ifdef ISL_INCLUDED */ /* AppFileName and AppPathName in the document are to be changed to AppCredential and AppSection*/ static CSSM_RETURN addin_VerifyModule( const CSSM_GUID *pModuleId, const CSSM_DATA *pCredential, const CSSM_DATA *pModuleName, const CSSM_DATA *pModulePath, CSSM_KEY_HIERARCHY KeyHierarchy, MAF_INTEG_MODULE_TYPE ModuleType, MAF_INTEG_CRED_INFO **ppCredInfo ) { CSSM_RETURN rv = CSSM_OK; MAF_INTEG_CRED_INFO *pCredInfo = NULL; /* Allocate the credential info structure */ pCredInfo = Addin_malloc( sizeof(MAF_INTEG_CRED_INFO), NULL ); if ( !pCredInfo ) { ERR( rv = CSSM_ERRCODE_MEMORY_ERROR ); } else { memset( pCredInfo, 0, sizeof(MAF_INTEG_CRED_INFO) ); DEBUG_EXEC( pCredInfo->MagicNumber = MAF_ICI_MAGIC_NUMBER ); memcpy( &pCredInfo->ModuleId, pModuleId, sizeof(CSSM_GUID) ); pCredInfo->KeyHierarchy = KeyHierarchy; pCredInfo->ModuleType = ModuleType; #ifdef ISL_INCLUDED { /* Integrity mode */ ISL_VERIFIED_SIGNATURE_ROOT_PTR pVerifiedRoot = NULL; ISL_VERIFIED_MODULE_PTR pModulePtr = NULL; /* ISL_MANIFEST_SECTION_PTR* ManifestSectionPtr = NULL;*/ ISL_CONST_DATA Credentials; ISL_CONST_DATA CredentialSearchPath; assert( pCredential ); Credentials.Data = pCredential->Data; Credentials.Length = pCredential->Length; CredentialSearchPath.Data = pModulePath->Data; CredentialSearchPath.Length = pModulePath->Length; if ( ( rv = addin_VerifyCredentials( Credentials, CredentialSearchPath, KeyHierarchy, &pVerifiedRoot ) ) == CSSM_OK ) { if ( ( rv = addin_GetVerifiedModulePointer( pModuleId, ModuleType, pVerifiedRoot, &pModulePtr ) ) == CSSM_OK ) { /* Fill-in the credential info structure */ pCredInfo->pModule = pModulePtr; } /* addin_GetModuleSection */ if ( rv != CSSM_OK ) { EISL_RecycleVerifiedSignatureRoot( pVerifiedRoot ); } } /* addin_VerifyCredentials */ } /* Integrity mode */ #else /* End integrity mode - Begin non-integrity mode */ { /* Non-integrity mode */ char szLibPath[256]; assert( pCredential && pModuleName && pModulePath && ppCredInfo ); assert( pModulePath->Data && pModuleName->Data ); assert( pModulePath->Length + pModuleName->Length + 2 < sizeof(szLibPath) ); /* Build the library path */ strcpy( szLibPath, (char*)pModulePath->Data ); #ifdef WIN32 strcat( szLibPath, "\\" ); #else strcat( szLibPath, "/" );; #endif strcat( szLibPath, (char*)pModuleName->Data ); if ( port_LoadLibrary( szLibPath, &pCredInfo->hModule ) != CSSM_OK ) { Addin_free( pCredInfo, NULL ); pCredInfo = NULL; ERR( rv = CSSMERR_CSSM_LIB_REF_NOT_FOUND ); } } /* non-integrity mode */ #endif /* End non-integrity mode */ /* Free the credential info structure in an error case */ if ( rv != CSSM_OK ) { Addin_free( pCredInfo, NULL ); pCredInfo = NULL; } } *ppCredInfo = pCredInfo; return rv; } CSSM_RETURN Addin_AuthenticateModule( const CSSM_GUID *pModuleId, CSSM_KEY_HIERARCHY KeyHierarchy, MAF_INTEG_MODULE_TYPE ModuleType, CSSM_PROC_ADDR RetAddr, ADDIN_MODULE_HANDLE *phModule ) { CSSM_RETURN rv = CSSM_OK; MLC_LOCK_REF LockRef = MLC_NULL_LOCK_REF; MAF_INTEG_CRED_INFO *pCredInfo = NULL; MAF_INTEG_CRED_INFO SearchKey; CSSM_DATA Credential = { 0, NULL }; CSSM_DATA ModuleName = { 0, NULL }; CSSM_DATA ModulePath = { 0, NULL }; CSSM_DB_RECORDTYPE MDSSchema = MDS_OBJECT_RECORDTYPE; DEBUG_EXEC( assert( s_bIntegInitialized ) ); assert( pModuleId && phModule ); assert( ( KeyHierarchy == CSSM_KEY_HIERARCHY_INTEG ) || ( KeyHierarchy == CSSM_KEY_HIERARCHY_EXPORT ) ); /* Attempt to find a pre-verified credential for this module */ SearchKey.ModuleId = *pModuleId; SearchKey.KeyHierarchy = KeyHierarchy; DEBUG_EXEC( SearchKey.MagicNumber = MAF_ICI_MAGIC_NUMBER ); if ( ( rv = MLC_FindItem( &s_Credentials, (MLC_FIND_FUNC)addin_FindCredInfoByGuidAndHierarchy, (void*)&SearchKey, MLC_READ_LOCK, &LockRef, (void**)&pCredInfo ) ) != CSSM_OK ) { /* Not Found */ if ( rv == MLC_ERR_NOT_FOUND ) { /* Not found, verify the module */ /* Determine the MDS scheme to search */ switch ( ModuleType ) { case MAF_INTEG_MT_OTHER: case MAF_INTEG_MT_CSSM: { MDSSchema = MDS_OBJECT_RECORDTYPE; break; } case MAF_INTEG_MT_EMM: { MDSSchema = MDS_CDSADIR_EMM_RECORDTYPE; break; } default: { /* This error only matters in debug mode. If this line * is hit in release mode, CSSM_MDS_ERROR will be * returned. */ assert( 0 ); } } /* Fetch the information from MDS */ if ( ( rv = Addin_MDSGetCredentialInfo( pModuleId, MDSSchema, &Credential, &ModuleName, &ModulePath ) ) == CSSM_OK ) { /* Verify the module credentials */ if ( ( rv = addin_VerifyModule( pModuleId, &Credential, &ModuleName, &ModulePath, KeyHierarchy, ModuleType, &pCredInfo ) ) == CSSM_OK ) { /* Check the return address (if not NULL) */ if ( ( RetAddr == NULL ) || ( rv = Addin_CheckAddressInModule( pCredInfo, RetAddr ) ) == CSSM_OK ) { /* Add the module credentials to the credential list */ if ( MLC_AddItem( &s_Credentials, (void*)pCredInfo, MLC_NO_LOCK, &LockRef ) != CSSM_OK ) { ERR( rv = CSSM_ERRCODE_INTERNAL_ERROR ); } } else { addin_DeleteCredentials( pCredInfo ); } } Addin_MDSReleaseCredentialInfo( &Credential, &ModuleName, &ModulePath ); } } else { ERR( rv = CSSM_ERRCODE_INTERNAL_ERROR ); } } /* Not Found */ else { /* Found */ ASSERT_VALID_MICI_PTR( pCredInfo ); /* Already verified the module, recheck it */ if ( ( rv = Addin_ReverifyModule( pCredInfo ) ) == CSSM_OK ) { /* Check the return address to make sure it is valid */ if ( RetAddr != NULL ) { rv = Addin_CheckAddressInModule( pCredInfo, RetAddr ); } } /* Release the read lock on the credential */ MLC_ReleaseItem( MLC_READ_LOCK, LockRef ); } /* Found */ /* Assign the return value */ if ( rv == CSSM_OK ) { *phModule = (void*)pCredInfo; } else { *phModule = NULL; } return rv; } CSSM_RETURN Addin_CheckAddressInModule( ADDIN_MODULE_HANDLE hModule, CSSM_PROC_ADDR FuncAddr ) { CSSM_RETURN rv = CSSM_OK; #ifdef ISL_INCLUDED const MAF_INTEG_CRED_INFO *pInfo = (const MAF_INTEG_CRED_INFO*)hModule; ASSERT_VALID_MICI_PTR( pInfo ); if ( EISL_CheckAddressWithinModule( pInfo->pModule, (ISL_FUNCTION_PTR)FuncAddr ) != ISL_OK ) { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } #endif return rv; } CSSM_RETURN Addin_SelfCheck() { CSSM_RETURN rv = CSSM_OK; DEBUG_EXEC( assert( s_bIntegInitialized || s_bIntegInitializing ) ); #ifdef ISL_INCLUDED { ISL_VERIFIED_MODULE_PTR pVerifiedModule = NULL; /* Call ISL to do the real work */ pVerifiedModule = EISL_SelfCheck(); if ( pVerifiedModule == NULL ) { ERR( rv = CSSMERR_CSSM_SELF_CHECK_FAILED ); } else { EISL_RecycleVerifiedModuleCredentials( pVerifiedModule ); } } #endif return rv; } CSSM_RETURN Addin_GetProcAddress( ADDIN_MODULE_HANDLE hModule, const char *FunctionName, CSSM_PROC_ADDR *pFunction ) { CSSM_RETURN rv = CSSM_OK; const MAF_INTEG_CRED_INFO *pCredInfo = hModule; assert( FunctionName && pFunction && hModule ); ASSERT_VALID_MICI_PTR( hModule ); #ifdef ISL_INCLUDED { /* Integrity configuration */ ISL_CONST_DATA ConstData; ISL_FUNCTION_PTR ISLFunctionPtr; ConstData.Length = strlen( FunctionName ); ConstData.Data = (const unsigned char*)FunctionName; ISLFunctionPtr = EISL_LocateProcedureAddress( pCredInfo->pModule, ConstData ); if ( ( EISL_CheckAddressWithinModule( pCredInfo->pModule, #ifdef __arch64__ (ISL_FUNCTION_PTR)(*(void **)ISLFunctionPtr))) == ISL_FAIL ) #else ISLFunctionPtr )) == ISL_FAIL ) #endif { ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } else { *pFunction = (CSSM_PROC_ADDR)ISLFunctionPtr; } } /* Integrity configuration */ #else { /* Non-integrity configuration */ if ( port_GetProcAddress( pCredInfo->hModule, FunctionName, pFunction ) != CSSM_OK ) { /* Not really the correct error code here, but it is the same * response that the caller will get with integrity on. */ ERR( rv = CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL ); } } /* Non-integrity configuration */ #endif return rv; } /*************************************************************************/ /***** Functions Required by EISL VerifyAndLoad APIs *********************/ /*************************************************************************/ #ifdef ISL_INCLUDED /* These functions return the default root name and key values. The MAF * always supplies these to the functions, so these are just place holders. */ int EISL_RetrieveRootIssuerKey( ISL_CALLOUT_DATA *Name) { return 0; } int EISL_RetrieveRootIssuerName( ISL_CALLOUT_DATA *Name) { return 0; } /*************************************************************************/ /***** Functions Required by EISL Self-Check *****************************/ /*************************************************************************/ void EISL_RetrieveSelfCheckSectionName( ISL_CALLOUT_DATA *Name) { uint32 len = strlen(ADDIN_SELF_CHECK_SECTION); if (len > Name->length) goto FAIL; strcpy( (char*)Name->value, ADDIN_SELF_CHECK_SECTION); Name->length = len; return; FAIL: Name->length = 0; return; } void EISL_RetrieveSelfCheckCredentials( ISL_CALLOUT_DATA *Name, ISL_CALLOUT_DATA *Path) { CSSM_DATA Credential; CSSM_DATA ModulePath; CSSM_DATA ModuleName; if ( Addin_MDSGetCredentialInfo( &ADDIN_GUID, MDS_CDSADIR_COMMON_RECORDTYPE, &Credential, &ModuleName, &ModulePath ) == CSSM_OK ) { memcpy( Name->value, Credential.Data, Credential.Length ); Name->length = Credential.Length; memcpy( Path->value, ModulePath.Data, ModulePath.Length ); Path->length = ModulePath.Length; Addin_MDSReleaseCredentialInfo( &Credential, &ModuleName, &ModulePath ); } } void EISL_RetrieveSelfCheckCredentialsSize( uint32 *Size) { CSSM_DATA Credential; CSSM_DATA ModulePath; CSSM_DATA ModuleName; if ( Size ) { if ( Addin_MDSGetCredentialInfo( &ADDIN_GUID, MDS_CDSADIR_COMMON_RECORDTYPE, &Credential, &ModuleName, &ModulePath ) == CSSM_OK ) { *Size = Credential.Length; Addin_MDSReleaseCredentialInfo( &Credential, &ModuleName, &ModulePath ); } } } #endif /* ifdef ISL_INCLUDED */