📄 int_api.c
字号:
attributePtr = prevPtr;
}
return( ( void * ) attributePtr );
}
void *attributeFindEnd( const void *attributePtr,
GETATTRFUNCTION getAttrFunction )
{
CRYPT_ATTRIBUTE_TYPE groupID;
if( attributePtr == NULL )
return( NULL );
/* Move forwards until we're just before the start of the next
attribute */
getAttrFunction( attributePtr, &groupID, NULL, NULL, ATTR_CURRENT );
while( TRUE )
{
CRYPT_ATTRIBUTE_TYPE nextGroupID;
const void *nextPtr;
nextPtr = getAttrFunction( attributePtr, &nextGroupID, NULL, NULL,
ATTR_NEXT );
if( nextPtr == NULL || nextGroupID != groupID )
/* We've reached the end of the list or a different attribute
group, this is the end of the current group */
break;
attributePtr = nextPtr;
}
return( ( void * ) attributePtr );
}
/* Find an attribute in a list of attributes */
void *attributeFind( const void *attributePtr,
GETATTRFUNCTION getAttrFunction,
const CRYPT_ATTRIBUTE_TYPE attributeID,
const CRYPT_ATTRIBUTE_TYPE instanceID )
{
CRYPT_ATTRIBUTE_TYPE currAttributeID, currInstanceID;
if( attributePtr == NULL )
return( NULL );
/* Find the attribute in the list */
getAttrFunction( attributePtr, NULL, &currAttributeID, NULL,
ATTR_CURRENT );
while( attributePtr != NULL && currAttributeID != attributeID )
attributePtr = getAttrFunction( attributePtr, NULL,
&currAttributeID, NULL,
ATTR_NEXT );
if( instanceID == CRYPT_ATTRIBUTE_NONE )
/* We're not looking for a particular instance, we're done */
return( ( void * ) attributePtr );
/* Find the attribute instance */
getAttrFunction( attributePtr, NULL, &currAttributeID, &currInstanceID,
ATTR_CURRENT );
while( attributePtr != NULL && currAttributeID == attributeID )
{
if( currInstanceID == instanceID )
return( ( void * ) attributePtr );
attributePtr = getAttrFunction( attributePtr, NULL,
&currAttributeID, &currInstanceID,
ATTR_NEXT );
}
return( NULL );
}
/* Find the next instance of an attribute in an attribute group. This is
used to step through multiple instances of an attribute, for example in
a cert extension containing a SEQUENCE OF <attribute> */
void *attributeFindNextInstance( const void *attributePtr,
GETATTRFUNCTION getAttrFunction )
{
CRYPT_ATTRIBUTE_TYPE groupID, attributeID;
CRYPT_ATTRIBUTE_TYPE currGroupID, currAttributeID;
if( attributePtr == NULL )
return( NULL );
/* Skip the current field */
getAttrFunction( attributePtr, &groupID, &attributeID, NULL,
ATTR_CURRENT );
attributePtr = getAttrFunction( attributePtr, &currGroupID,
&currAttributeID, NULL,
ATTR_NEXT );
/* Step through the remaining attributes in the group looking for
another occurrence of the current attribute */
while( attributePtr != NULL && currGroupID == groupID )
{
if( currAttributeID == attributeID )
return( ( void * ) attributePtr );
attributePtr = getAttrFunction( attributePtr, &currGroupID,
&currAttributeID, NULL,
ATTR_NEXT );
}
/* We couldn't find another instance of the attribute in this group */
return( NULL );
}
/* Move the attribute cursor relative to the current cursor position */
const void *attributeMoveCursor( const void *currentCursor,
GETATTRFUNCTION getAttrFunction,
const CRYPT_ATTRIBUTE_TYPE attributeMoveType,
const int cursorMoveType )
{
const void *newCursor = currentCursor, *lastCursor = NULL;
const BOOLEAN absMove = ( cursorMoveType == CRYPT_CURSOR_FIRST || \
cursorMoveType == CRYPT_CURSOR_LAST ) ? \
TRUE : FALSE;
int count;
assert( attributeMoveType == CRYPT_ATTRIBUTE_CURRENT_GROUP || \
attributeMoveType == CRYPT_ATTRIBUTE_CURRENT || \
attributeMoveType == CRYPT_ATTRIBUTE_CURRENT_INSTANCE );
assert( cursorMoveType <= CRYPT_CURSOR_FIRST && \
cursorMoveType >= CRYPT_CURSOR_LAST );
/* Positioning in null attribute lists is always unsuccessful */
if( currentCursor == NULL )
return( NULL );
/* Set the amount that we want to move by based on the position code.
This means that we can handle the movement in a simple while loop
instead of having to special-case it for moves by one item */
count = absMove ? INT_MAX : 1;
/* Moving by attribute or attribute instance is relatively simple. For
attributes we move backwards or forwards until we either run out of
attributes or the next attribute belongs to a different group. For
attribute instances we move similarly, except that we stop when we
reach an attribute whose group type, attribute type, and instance
type don't match the current one. We have to explicitly keep track
of whether the cursor was successfully moved rather than checking
that it's value has changed because some object types maintain an
attribute-internal virtual cursor that can return the same attribute
pointer multiple times */
if( attributeMoveType == CRYPT_ATTRIBUTE_CURRENT )
{
CRYPT_ATTRIBUTE_TYPE groupID;
BOOLEAN cursorMoved = FALSE;
getAttrFunction( currentCursor, &groupID, NULL, NULL,
ATTR_CURRENT );
if( cursorMoveType == CRYPT_CURSOR_FIRST || \
cursorMoveType == CRYPT_CURSOR_PREVIOUS )
{
CRYPT_ATTRIBUTE_TYPE prevGroupID;
const void *prevCursor;
prevCursor = getAttrFunction( newCursor, &prevGroupID, NULL,
NULL, ATTR_PREV );
while( count-- > 0 && prevCursor != NULL && \
prevGroupID == groupID )
{
newCursor = prevCursor;
prevCursor = getAttrFunction( newCursor, &prevGroupID, NULL,
NULL, ATTR_PREV );
cursorMoved = TRUE;
}
}
else
{
CRYPT_ATTRIBUTE_TYPE nextGroupID;
const void *nextCursor;
nextCursor = getAttrFunction( newCursor, &nextGroupID, NULL,
NULL, ATTR_NEXT );
while( count-- > 0 && nextCursor != NULL && \
nextGroupID == groupID )
{
newCursor = nextCursor;
nextCursor = getAttrFunction( newCursor, &nextGroupID, NULL,
NULL, ATTR_NEXT );
cursorMoved = TRUE;
}
}
if( !absMove && !cursorMoved )
return( NULL );
return( newCursor );
}
if( attributeMoveType == CRYPT_ATTRIBUTE_CURRENT_INSTANCE )
{
CRYPT_ATTRIBUTE_TYPE groupID, attributeID, instanceID;
BOOLEAN cursorMoved = FALSE;
getAttrFunction( currentCursor, &groupID, &attributeID, &instanceID,
ATTR_CURRENT );
if( cursorMoveType == CRYPT_CURSOR_FIRST || \
cursorMoveType == CRYPT_CURSOR_PREVIOUS )
{
CRYPT_ATTRIBUTE_TYPE prevGroupID, prevAttrID, prevInstID;
const void *prevCursor;
prevCursor = getAttrFunction( newCursor, &prevGroupID,
&prevAttrID, &prevInstID,
ATTR_PREV );
while( count-- > 0 && prevCursor != NULL && \
prevGroupID == groupID && prevAttrID == attributeID && \
prevInstID == instanceID )
{
newCursor = prevCursor;
prevCursor = getAttrFunction( newCursor, &prevGroupID,
&prevAttrID, &prevInstID,
ATTR_PREV );
cursorMoved = TRUE;
}
}
else
{
CRYPT_ATTRIBUTE_TYPE nextGroupID, nextAttrID, nextInstID;
const void *nextCursor;
nextCursor = getAttrFunction( newCursor, &nextGroupID,
&nextAttrID, &nextInstID,
ATTR_NEXT );
while( count-- > 0 && nextCursor != NULL && \
nextGroupID == groupID && nextAttrID == attributeID && \
nextInstID == instanceID )
{
newCursor = nextCursor;
nextCursor = getAttrFunction( newCursor, &nextGroupID,
&nextAttrID, &nextInstID,
ATTR_NEXT );
cursorMoved = TRUE;
}
}
if( !absMove && !cursorMoved )
return( NULL );
return( newCursor );
}
/* Moving by attribute group is a bit more complex. First we find the
start or end of the current group. Then we move to the start of the
previous (via ATTR_PREV and attributeFindStart()), or start of the
next (via ATTR_NEXT) group beyond that. This has the effect of
moving us from anywhere in the current group to the start of the
preceding or following group. Finally, we repeat this as required */
while( count-- > 0 && newCursor != NULL )
{
lastCursor = newCursor;
if( cursorMoveType == CRYPT_CURSOR_FIRST || \
cursorMoveType == CRYPT_CURSOR_PREVIOUS )
{
/* Move from the start of the current group to the start of the
preceding group */
newCursor = attributeFindStart( newCursor, getAttrFunction );
newCursor = getAttrFunction( newCursor, NULL, NULL, NULL,
ATTR_PREV );
if( newCursor != NULL )
newCursor = attributeFindStart( newCursor, getAttrFunction );
}
else
{
/* Move from the end of the current group to the start of the
next group */
newCursor = attributeFindEnd( newCursor, getAttrFunction );
newCursor = getAttrFunction( newCursor, NULL, NULL, NULL,
ATTR_NEXT );
}
}
assert( lastCursor != NULL ); /* We went through loop at least once */
/* If the new cursor is NULL, we've reached the start or end of the
attribute list */
if( newCursor == NULL )
/* If it's an absolute move we've reached our destination, otherwise
there's nowhere left to move to. We move to the start of the
first or last attribute that we got to before we ran out of
attributes to make sure that we don't fall off the start/end of
the list */
return( absMove ? \
attributeFindStart( lastCursor, getAttrFunction ) : NULL );
/* We've found what we were looking for */
return( newCursor );
}
/****************************************************************************
* *
* Enveloping Functions *
* *
****************************************************************************/
/* General-purpose enveloping functions, used by various high-level
protocols */
int envelopeWrap( const void *inData, const int inDataLength, void *outData,
int *outDataLength, const int outDataMaxLength,
const CRYPT_FORMAT_TYPE formatType,
const CRYPT_CONTENT_TYPE contentType,
const CRYPT_HANDLE iCryptKey )
{
CRYPT_ENVELOPE iCryptEnvelope;
MESSAGE_CREATEOBJECT_INFO createInfo;
RESOURCE_DATA msgData;
const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength + 512 );
int status;
assert( isReadPtr( inData, inDataLength ) );
assert( inDataLength > 16 );
assert( isWritePtr( outData, outDataMaxLength ) );
assert( outDataMaxLength > 16 );
assert( isWritePtr( outDataLength, sizeof( int ) ) );
assert( contentType == CRYPT_CONTENT_NONE || \
( contentType > CRYPT_CONTENT_NONE && \
contentType < CRYPT_CONTENT_LAST ) );
assert( ( iCryptKey == CRYPT_UNUSED ) || \
isHandleRangeValid( iCryptKey ) );
*outDataLength = 0;
/* Create an envelope to wrap the data, add the encryption key if
necessary, and pop the wrapped result */
setMessageCreateObjectInfo( &createInfo, formatType );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT, &createInfo,
OBJECT_TYPE_ENVELOPE );
if( cryptStatusError( status ) )
return( status );
iCryptEnvelope = createInfo.cryptHandle;
krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &minBufferSize, CRYPT_ATTRIBUTE_BUFFERSIZE );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &inDataLength,
CRYPT_ENVINFO_DATASIZE );
if( cryptStatusOK( status ) && contentType != CRYPT_CONTENT_NONE )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &contentType,
CRYPT_ENVINFO_CONTENTTYPE );
if( cryptStatusOK( status ) && iCryptKey != CRYPT_UNUSED )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &iCryptKey,
CRYPT_ENVINFO_PUBLICKEY );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, ( void * ) inData, inDataLength );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
&msgData, 0 );
}
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, NULL, 0 );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
&msgData, 0 );
}
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, outData, outDataMaxLength );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_POPDATA,
&msgData, 0 );
}
krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );
if( cryptStatusOK( status ) )
*outDataLength = msgData.length;
return( status );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -