📄 efibis_authfxns.c
字号:
// when called. When this function returns the scan state points to the
// next byte past the length value.
//
// Parameters:
// scanState - (IN OUT) Holds information about the certificate and the
// state of the scan
// length - (OUT) Returns the retrieved length value if the function
// is successful.
//
// Returns:
// TRUE if successful, otherwise FALSE.
//
///////////////////////////////////////////////////////////////////////////////
static
BOOLEAN
ExtractLength(
IN OUT CERT_SCAN_STATE *scanState,
OUT UINT32 *length
)
{
BOOLEAN ok_so_far;
UINT8 length_of_length;
// The first byte of a length field is as follows:
// 8 7 6 5 4 3 2 1
// +---+---+---+---+---+---+---+---+
// |S/L| primary_length |
// +---+---+---+---+---+---+---+---+
// S/L indicates a short or long length form
// 0 primary_length is the actual length of the content
// 1 primary_length is a "length of length" or "indefinite" form
//
// In the case of S/L=1, primary_length!=0:
// indicates that the next primary_length bytes are the length in
// big-endian form. Since we don't expect to encounter extremely long
// contents, we'll simply report a failure if the "length of length" is
// more than 4 bytes.
//
// In the case of S/L=1, primary_length==0:
// indicates that the length is indefinite and the contents is
// terminated by a special end-of-contents value. We'll simply report
// a failure for this case, since we don't expect to
// encounter indefinite lengths.
#define BISCERT_SL_MASK (0x80)
#define BISCERT_LENGTH_MASK (0x7F)
#define BISCERT_INDEFINTE_LENGTH (0x80)
#define BISCERT_MAX_LEN_OF_LEN (sizeof(UINT32))
ok_so_far = IsWithinBuffer(
scanState, // scanState
1); // numBytes
if (ok_so_far)
{
length_of_length = scanState->certBuffer[scanState->currentOffset];
scanState->currentOffset++;
if (length_of_length == BISCERT_INDEFINTE_LENGTH)
{
ok_so_far = FALSE; // Don't handle indefinite length form
}
}
if (ok_so_far)
{
if (! (length_of_length & BISCERT_SL_MASK))
{
// Using short form
* length = (UINT32) length_of_length;
}
else
{
// Using long form
length_of_length &= BISCERT_LENGTH_MASK;
if (length_of_length > BISCERT_MAX_LEN_OF_LEN)
{
// Longer than we want to handle
ok_so_far = FALSE;
}
if (ok_so_far)
{
// Check containment of length bytes
ok_so_far = IsWithinBuffer(
scanState, // scanState
length_of_length); // numBytes
}
if (ok_so_far)
{
// Extract big-endian multiple-byte length
UINT32 i;
UINT32 temp_length;
temp_length = 0;
for (i=0; i<length_of_length; i++)
{
temp_length *= 256;
temp_length += (UINT32)
scanState->certBuffer[scanState->currentOffset];
scanState->currentOffset ++;
}
* length = temp_length;
}
} // else long form
} // if ok_so_far
return ok_so_far;
} // ExtractLength
///////////////////////////////////////////////////////////////////////////////
// Function Name: IsWithinBuffer
//
// Description:
// This internal function tests whether the desired number of bytes
// are contained within the remaining certificate buffer (that is,
// within the array index from currentOffset onward).
//
// Parameters:
// scanState - (IN) Holds information about the certificate and the state
// of the scan
// numBytes - (IN) Supplies the number of bytes desired in the remaining
// buffer.
//
// Returns:
// TRUE if at least this many bytes remain in the buffer, otherwise
// FALSE
//
///////////////////////////////////////////////////////////////////////////////
static
BOOLEAN
IsWithinBuffer(
IN CERT_SCAN_STATE *scanState,
IN UINT32 numBytes
)
{
UINT32 num_bytes_remaining;
BOOLEAN to_return;
num_bytes_remaining = scanState->certLength - scanState->currentOffset;
if (num_bytes_remaining >= numBytes)
{
to_return = TRUE;
}
else
{
to_return = FALSE;
}
return to_return;
} // IsWithinBuffer
///////////////////////////////////////////////////////////////////////////////
// Function Name: EFIBIS_Authorization_fn
//
// Description: This is the interactive version of the authorization
// function. When an authorize request is received it checks to
// see if a request has already been received. If so, it checks
// the signing certificate with the one that was stored on a
// previous authorization call. If it matches the IsAuthorized
// is set to TRUE. If it is not the same certificate, or it
// is a new request the user us prompted for a yes/no decision
// to allow the request.
//
// Parameters:
// This - (IN)
// CallingFunction - (IN) tells the operation for authorization needed
// Credentials - (IN)
// CredentialsSigner - (IN)
// DataObject - (IN)
// Reserved - (IN) Reserved
// IsAuthorized - (OUT) TRUE if authorized, FALSE otherwise
//
// Returns:
// Status code
//
///////////////////////////////////////////////////////////////////////////////
EFI_STATUS
EFIBIS_Authorization_fn(
IN EFI_BIS_DEFAULT_AUTH_INTERFACE *This,
IN EFI_BIS_CALLING_FUNCTION CallingFunction,
IN EFI_BIS_DATA *Credentials,
IN EFI_BIS_DATA *CredentialsSigner,
IN EFI_BIS_DATA *DataObject,
IN VOID *Reserved,
OUT BOOLEAN *IsAuthorized
)
{
AUTHORIZATION_STATE *auth_state;
EFI_STATUS to_return;
BOOLEAN same_authority;
// Parameter checking
to_return = EFI_INVALID_PARAMETER; // assume fail till success
if ((CallingFunction == BisCallingFunctionVerify) ||
(CallingFunction == BisCallingFunctionUpdate))
{
if (This)
{
if (Credentials && Credentials->Data == NULL)
{
if (CredentialsSigner && CredentialsSigner->Data == NULL)
{
if (IsAuthorized)
{
if (Reserved == NULL)
{
if (CallingFunction == BisCallingFunctionVerify)
{
if (DataObject && DataObject->Data != NULL)
{
to_return = EFI_SUCCESS;
}
}
else
{
// data object can be null in this case
to_return = EFI_SUCCESS;
}
} // End of if (Reserved == NULL)
} // End of if (IsAuthorized)
} // End of if (CredentialsSigner && CredentialsSigner->Data)
} // End of if (Credentials && Credentials->Data)
} // End of if (This)
} // End of if (CallingFunction == (BisCallingFunctionVerify || ..
if (EFI_SUCCESS == to_return)
{
auth_state = (AUTHORIZATION_STATE *) This->InstanceData;
same_authority = MatchesAuthorityCert(
auth_state, // rememberedAuthority
CredentialsSigner); // thisAuthority
if (same_authority)
{
// This identity is the one we have previously authorized, so
// simply authorize the operation with no further user interaction.
* IsAuthorized = TRUE;
} // if same_authority
else
{ // User interaction is required
BOOLEAN user_authorizes;
// Remove any remembered certificate we currently have. This may
// require modification if the sample is altered to use dynamic
// allocation for the remembered certificate.
auth_state->authorityCertLen = 0;
auth_state->hasAuthorityCert = FALSE;
if (auth_state->authorityCert != NULL)
{
FreePool(auth_state->authorityCert);
}
// Ask the user
user_authorizes = QueryUserAuthorization(
CallingFunction, // CallingFunction
CredentialsSigner); // thisAuthority
if (user_authorizes)
{
// Save the new authority
to_return = SaveAuthority(
auth_state, // rememberedAuthority
CredentialsSigner); // thisAuthority
// And propagate the "authorized" result
* IsAuthorized = TRUE;
}
else
{
// Propagate the "not authorized" result. Old authority has been
// erased.
* IsAuthorized = FALSE;
}
} // else user interaction
} // End of if (EFI_SUCCESS == to_return)
return to_return;
} // End of EFIBIS_Authorization_fn
#else // End of #ifdef INTERACTIVE_AUTHORIZATION_REQUIRED
///////////////////////////////////////////////////////////////////////////////
// Function Name: EFIBIS_Authorization_fn
//
// Description: This is the non interactive implementation of the
// authorization function. It does simple parameter checking
// and then sets IsAuthorized to TRUE.
//
// Parameters:
// This - (IN)
// CallingFunction - (IN) tells the operation for authorization needed
// Credentials - (IN)
// CredentialsSigner - (IN)
// DataObject - (IN)
// Reserved - (IN) Reserved
// IsAuthorized - (OUT) TRUE if authorized, FALSE otherwise
//
// Returns:
// Status code
//
///////////////////////////////////////////////////////////////////////////////
EFI_STATUS
EFIBIS_Authorization_fn(
IN EFI_BIS_DEFAULT_AUTH_INTERFACE *This,
IN EFI_BIS_CALLING_FUNCTION CallingFunction,
IN EFI_BIS_DATA *Credentials,
IN EFI_BIS_DATA *CredentialsSigner,
IN EFI_BIS_DATA *DataObject,
IN VOID *Reserved,
OUT BOOLEAN *IsAuthorized
)
{
EFI_STATUS to_return;
// Parameter checking
to_return = EFI_INVALID_PARAMETER; // assume fail till success
if ((CallingFunction == BisCallingFunctionVerify) ||
(CallingFunction == BisCallingFunctionUpdate))
{
if (This)
{
if (Credentials && Credentials->Data != NULL)
{
if (CredentialsSigner && CredentialsSigner->Data != NULL)
{
if (IsAuthorized)
{
if (Reserved == NULL)
{
if (CallingFunction == BisCallingFunctionVerify)
{
if (DataObject && DataObject->Data != NULL)
{
to_return = EFI_SUCCESS;
}
}
else
{
// data object can be null in this case
to_return = EFI_SUCCESS;
}
} // End of if (Reserved == NULL)
} // End of if (IsAuthorized)
} // End of if (CredentialsSigner && CredentialsSigner->Data)
} // End of if (Credentials && Credentials->Data)
} // End of if (This)
} // End of if (CallingFunction == (BisCallingFunctionVerify || ..
if (EFI_SUCCESS == to_return)
{
* IsAuthorized = TRUE;
} // End of if (EFI_SUCCESS == to_return)
return to_return;
} // End of EFIBIS_Authorization_fn
#endif // ! defined INTERACTIVE_AUTHORIZATION_REQUIRED
//
// EFIBIS_InitAuthFxnModule - called by efibis_basecode.c
//
// Parm:
// EFI_BIS_DEFAULT_AUTH_INTERFACE **authInterface
//
// Description:
// fills in the pointer to the auth interface passed as a parm.
//
// returns: true if all ok.
//
EFI_STATUS
EFIBIS_InitAuthFxnModule(
EFI_BIS_DEFAULT_AUTH_INTERFACE **authInterface
)
{
EFI_STATUS Status= EFI_SUCCESS;
EFI_BIS_DEFAULT_AUTH_INTERFACE *authI_F = NULL;
EFI_HANDLE tempHandle;
#ifdef INTERACTIVE_AUTHORIZATION_REQUIRED
AUTHORIZATION_STATE *authorizationState = NULL;
#endif
tempHandle = NULL;
authI_F = x_malloc (sizeof(EFI_BIS_DEFAULT_AUTH_INTERFACE));
if ( authI_F == NULL)
{
Status= EFI_OUT_OF_RESOURCES;
}
#ifdef INTERACTIVE_AUTHORIZATION_REQUIRED
// Only allocate it if the interactive version of auth fxns are used
//Allocate space for the modules instance data.
authorizationState= AllocateZeroPool( sizeof(AUTHORIZATION_STATE) );
if ( authorizationState == NULL )
{
Status= EFI_OUT_OF_RESOURCES;
}
if (EFI_SUCCESS == Status)
{
// Initiallize authorization specific data
authorizationState->hasAuthorityCert = FALSE;
authorizationState->authorityCertLen = 0;
authorizationState->authorityCert = NULL;
}
// Authorization state is the instance data defined
authI_F->InstanceData= (VOID*)authorizationState;
#else
// There is no real instance data needed
authI_F->InstanceData= (VOID*)authI_F;
#endif
// Fill out the interface structur
if ( Status == EFI_SUCCESS)
{
authI_F->CheckCredentials = EFIBIS_Authorization_fn;
*authInterface= authI_F;
}
//Free memory if we are going to fail for EFI reasons
if ( Status != EFI_SUCCESS )
{
#ifdef INTERACTIVE_AUTHORIZATION_REQUIRED
// Only clean it up if the interactive version of auth fxns are used
if ( authorizationState != NULL){
FreePool( authorizationState );
}
#endif
if ( authI_F != NULL){
gBS->FreePool( authI_F );
}
}
return Status;
}
//eof
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -