📄 int_api.c
字号:
dynBuf->length = 0;
/* If we're just creating a placeholder buffer, return now */
if( cryptHandle == CRYPT_UNUSED )
return( CRYPT_OK );
/* Get the data from the object */
setMessageData( &msgData, NULL, 0 );
status = krnlSendMessage( cryptHandle, message, &msgData,
attributeType );
if( cryptStatusError( status ) )
return( status );
if( msgData.length > DYNBUF_SIZE )
{
/* The data is larger than the built-in buffer size, dynamically
allocate a larger buffer */
if( ( dataPtr = clDynAlloc( "dynCreate", msgData.length ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
msgData.data = dataPtr;
status = krnlSendMessage( cryptHandle, message, &msgData,
attributeType );
if( cryptStatusError( status ) )
{
clFree( "dynCreate", dataPtr );
return( status );
}
dynBuf->data = dataPtr;
}
else
{
/* The data will fit into the built-in buffer, read it directly into
the buffer */
msgData.data = dynBuf->data;
status = krnlSendMessage( cryptHandle, message, &msgData,
attributeType );
if( cryptStatusError( status ) )
return( status );
}
dynBuf->length = msgData.length;
return( CRYPT_OK );
}
void dynDestroy( DYNBUF *dynBuf )
{
assert( isWritePtr( dynBuf, sizeof( DYNBUF ) ) );
assert( dynBuf->length == 0 || \
isWritePtr( dynBuf->data, dynBuf->length ) );
if( dynBuf->length <= 0 )
return;
zeroise( dynBuf->data, dynBuf->length );
if( dynBuf->data != dynBuf->dataBuffer )
clFree( "dynDestroy", dynBuf->data );
}
/****************************************************************************
* *
* Memory Management Routines *
* *
****************************************************************************/
/* Memory pool management functions. When allocating many little blocks of
memory, especially in resource-constrained systems, it's better if we pre-
allocate a small memory pool ourselves and grab chunks of it as required,
falling back to dynamically allocating memory later on if we exhaust the
pool. The following functions implement the custom memory pool
management */
typedef struct {
void *storage; /* Memory pool */
int storagePos, storageSize; /* Current usage and total size of pool */
} MEMPOOL_INFO;
void initMemPool( void *statePtr, void *memPool, const int memPoolSize )
{
MEMPOOL_INFO *state = ( MEMPOOL_INFO * ) statePtr;
assert( isWritePtr( state, sizeof( MEMPOOL_INFO ) ) );
assert( isWritePtr( memPool, memPoolSize ) );
memset( state, 0, sizeof( MEMPOOL_INFO ) );
state->storage = memPool;
state->storageSize = memPoolSize;
}
void *getMemPool( void *statePtr, const int size )
{
MEMPOOL_INFO *state = ( MEMPOOL_INFO * ) statePtr;
BYTE *allocPtr = state->storage;
const int allocSize = roundUp( size, sizeof( int ) );
assert( isWritePtr( state, sizeof( MEMPOOL_INFO ) ) );
assert( isWritePtr( state->storage, state->storageSize ) );
/* If we can't satisfy the request from the memory pool, we have to
allocate it dynamically */
if( state->storagePos + allocSize > state->storageSize )
return( clDynAlloc( "getMemPool", size ) );
/* We can satisfy the request from the pool */
allocPtr += state->storagePos;
state->storagePos += allocSize;
return( allocPtr );
}
void freeMemPool( void *statePtr, void *memblock )
{
MEMPOOL_INFO *state = ( MEMPOOL_INFO * ) statePtr;
assert( isWritePtr( state, sizeof( MEMPOOL_INFO ) ) );
assert( isWritePtr( state->storage, state->storageSize ) );
/* If the memory block is within the pool, there's nothing to do */
if( memblock >= state->storage && \
memblock < ( void * ) ( ( BYTE * ) state->storage + \
state->storageSize ) )
return;
/* It's outside the pool and therefore dynamically allocated, free it */
clFree( "freeMemPool", memblock );
}
/* Debugging malloc() that dumps memory usage diagnostics to stdout */
#ifdef CONFIG_DEBUG_MALLOC
#ifdef __WIN32__
#include <direct.h>
#endif /* __WIN32__ */
#ifdef __WINCE__
static void wcPrintf( const char *format, ... )
{
wchar_t wcBuffer[ 1024 ];
char buffer[ 1024 ];
va_list argPtr;
va_start( argPtr, format );
vsprintf( buffer, format, argPtr );
va_end( argPtr );
mbstowcs( wcBuffer, buffer, strlen( buffer ) + 1 );
NKDbgPrintfW( wcBuffer );
}
#endif /* __WINCE__ */
static int clAllocIndex = 0;
void *clAllocFn( const char *fileName, const char *fnName,
const int lineNo, size_t size )
{
char buffer[ 512 ];
BYTE *memPtr;
#ifndef __WINCE__
int length;
#endif /* __WINCE__ */
/* Strip off the leading path components if we can to reduce the amount
of noise in the output */
#if defined( __WIN32__ ) || defined( __UNIX__ )
if( getcwd( buffer, 512 ) != NULL )
fileName += strlen( buffer ) + 1; /* Skip leading path + '/' */
#endif /* __WIN32__ || __UNIX__ */
#ifdef __WINCE__
wcPrintf( "ALLOC: %s:%s:%d %4d - %d bytes.\n", fileName, fnName, lineNo,
clAllocIndex, size );
#else
length = printf( "ALLOC: %s:%s:%d", fileName, fnName, lineNo );
while( length < 46 )
{
putchar( ' ' );
length++;
}
printf( " %4d - %d bytes.\n", clAllocIndex, size );
#endif /* __WINCE__ */
if( ( memPtr = malloc( size + 4 ) ) == NULL )
return( NULL );
mputLong( memPtr, clAllocIndex ); /* Implicit memPtr += 4 */
clAllocIndex++;
return( memPtr );
}
void clFreeFn( const char *fileName, const char *fnName,
const int lineNo, void *memblock )
{
char buffer[ 512 ];
BYTE *memPtr = ( BYTE * ) memblock - 4;
int index;
#ifndef __WINCE__
int length;
#endif /* __WINCE__ */
/* Strip off the leading path components if we can to reduce the amount
of noise in the output */
#if defined( __WIN32__ ) || defined( __UNIX__ )
if( getcwd( buffer, 512 ) != NULL )
fileName += strlen( buffer ) + 1; /* Skip leading path + '/' */
#endif /* __WIN32__ || __UNIX__ */
index = mgetLong( memPtr );
#ifdef __WINCE__
wcPrintf( "ALLOC: %s:%s:%d %4d.\n", fileName, fnName, lineNo, index );
#else
length = printf( "ALLOC: %s:%s:%d", fileName, fnName, lineNo );
while( length < 46 )
{
putchar( ' ' );
length++;
}
printf( " %4d.\n", index );
#endif /* __WINCE__ */
free( memPtr - 4 );
}
#endif /* CONFIG_DEBUG_MALLOC */
/****************************************************************************
* *
* Stream Export/Import Routines *
* *
****************************************************************************/
/* Export attribute or certificate data to a stream. In theory we would
have to export this via a dynbuf and then write it to the stream, however
we can save some overhead by writing it directly to the stream's buffer */
int exportAttributeToStream( void *streamPtr, const CRYPT_HANDLE cryptHandle,
const CRYPT_ATTRIBUTE_TYPE attributeType,
const int attributeLength )
{
RESOURCE_DATA msgData;
STREAM *stream = streamPtr;
const int length = ( attributeLength == CRYPT_USE_DEFAULT ) ? \
sMemDataLeft( stream ) : attributeLength;
int status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( sStatusOK( stream ) );
assert( cryptHandle == SYSTEM_OBJECT_HANDLE || \
isHandleRangeValid( cryptHandle ) );
assert( isAttribute( attributeType ) || \
isInternalAttribute( attributeType ) );
assert( attributeLength == CRYPT_USE_DEFAULT || \
( attributeLength >= 8 && attributeLength <= 16384 ) );
/* Before we try the export, make sure that everything is OK with the
stream */
if( !sStatusOK( stream ) )
return( sGetStatus( stream ) );
if( sMemDataLeft( stream ) < 2 )
return( CRYPT_ERROR_UNDERFLOW );
/* Export the attribute to the stream */
setMessageData( &msgData, sMemBufPtr( stream ), length );
status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, attributeType );
if( cryptStatusOK( status ) )
status = sSkip( stream, msgData.length );
return( status );
}
int exportCertToStream( void *streamPtr,
const CRYPT_CERTIFICATE cryptCertificate,
const CRYPT_CERTFORMAT_TYPE certFormatType )
{
RESOURCE_DATA msgData;
STREAM *stream = streamPtr;
int status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( sStatusOK( stream ) );
assert( isHandleRangeValid( cryptCertificate ) );
assert( certFormatType > CRYPT_CERTFORMAT_NONE && \
certFormatType < CRYPT_CERTFORMAT_LAST );
/* Before we try the export, make sure that everything is OK with the
stream */
if( !sStatusOK( stream ) )
return( sGetStatus( stream ) );
if( !sIsNullStream( stream ) && \
sMemDataLeft( stream ) < MIN_CRYPT_OBJECTSIZE )
return( CRYPT_ERROR_UNDERFLOW );
/* Export the cert to the stream */
setMessageData( &msgData, sMemBufPtr( stream ), sMemDataLeft( stream ) );
status = krnlSendMessage( cryptCertificate, IMESSAGE_CRT_EXPORT,
&msgData, certFormatType );
if( cryptStatusOK( status ) )
status = sSkip( stream, msgData.length );
return( status );
}
int importCertFromStream( void *streamPtr,
CRYPT_CERTIFICATE *cryptCertificate,
const int length,
const CRYPT_CERTTYPE_TYPE certType )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
STREAM *stream = streamPtr;
int status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( sStatusOK( stream ) );
assert( isWritePtr( cryptCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
assert( length > 0 && length < INT_MAX );
assert( ( certType > CRYPT_CERTTYPE_NONE && \
certType < CRYPT_CERTTYPE_LAST ) || \
( certType == CERTFORMAT_CTL ) );
/* Clear return value */
*cryptCertificate = CRYPT_ERROR;
/* Before we try the import, make sure that everything is OK with the
stream and parameters */
if( !sStatusOK( stream ) )
return( sGetStatus( stream ) );
if( length > sMemDataLeft( stream ) )
return( CRYPT_ERROR_UNDERFLOW );
/* Import the cert from the stream */
setMessageCreateObjectIndirectInfo( &createInfo, sMemBufPtr( stream ),
length, certType );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusOK( status ) )
{
status = sSkip( stream, length );
if( cryptStatusOK( status ) )
*cryptCertificate = createInfo.cryptHandle;
else
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
}
return( status );
}
/****************************************************************************
* *
* Attribute Location/Cursor Movement Routines *
* *
****************************************************************************/
/* Find the start and end of an attribute group from an attribute within
the group */
void *attributeFindStart( const void *attributePtr,
GETATTRFUNCTION getAttrFunction )
{
CRYPT_ATTRIBUTE_TYPE groupID;
if( attributePtr == NULL )
return( NULL );
/* Move backwards until we find the start of the attribute */
getAttrFunction( attributePtr, &groupID, NULL, NULL, ATTR_CURRENT );
while( TRUE )
{
CRYPT_ATTRIBUTE_TYPE prevGroupID;
const void *prevPtr;
prevPtr = getAttrFunction( attributePtr, &prevGroupID, NULL, NULL,
ATTR_PREV );
if( prevPtr == NULL || prevGroupID != groupID )
/* We've reached the start of the list or a different attribute
group, this is the start of the current group */
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -