📄 int_api.h
字号:
if( element->next != NULL ) \
element->next->prev = NULL; \
} \
else \
{ \
/* Delete from the middle or the end of the list */ \
element->prev->next = element->next; \
if( element->next != NULL ) \
element->next->prev = element->prev; \
} \
}
/****************************************************************************
* *
* Attribute List Manipulation Functions *
* *
****************************************************************************/
/* In order to work with attribute lists of different types, we need a
means of accessing the type-specific previous and next pointers and the
attribute ID information. The following callback function is passed to
all attribute-list manipulation functions and provides external access
to the required internal fields */
typedef enum {
ATTR_NONE, /* No attribute get type */
ATTR_CURRENT, /* Get details for current attribute */
ATTR_PREV, /* Get details for previous attribute */
ATTR_NEXT, /* Get details for next attribute */
ATTR_LAST /* Last valid attribute get type */
} ATTR_TYPE;
typedef const void * ( *GETATTRFUNCTION )( const void *attributePtr,
CRYPT_ATTRIBUTE_TYPE *groupID,
CRYPT_ATTRIBUTE_TYPE *attributeID,
CRYPT_ATTRIBUTE_TYPE *instanceID,
const ATTR_TYPE attrGetType );
void *attributeFindStart( const void *attributePtr,
GETATTRFUNCTION getAttrFunction );
void *attributeFindEnd( const void *attributePtr,
GETATTRFUNCTION getAttrFunction );
void *attributeFind( const void *attributePtr,
GETATTRFUNCTION getAttrFunction,
const CRYPT_ATTRIBUTE_TYPE attributeID,
const CRYPT_ATTRIBUTE_TYPE instanceID );
void *attributeFindNextInstance( const void *attributePtr,
GETATTRFUNCTION getAttrFunction );
const void *attributeMoveCursor( const void *currentCursor,
GETATTRFUNCTION getAttrFunction,
const CRYPT_ATTRIBUTE_TYPE attributeMoveType,
const int cursorMoveType );
/****************************************************************************
* *
* Time Functions *
* *
****************************************************************************/
/* In exceptional circumstances an attempt to read the time can fail,
returning either a garbage value (unsigned time_t) or -1 (signed time_t).
This can be problematic because many crypto protocols and operations use
the time at some point. In order to protect against this, we provide a
safe time-read function that returns either a sane time value or zero,
and for situations where the absolute time isn't critical an approximate
current-time function that returns either a sane time value or an
approximate value hardcoded in at compile time. Finally, we provide a
reliable time function used for operations such as signing certs and
timestamping that tries to get the time from a hardware time source if
one is available.
The following two values define the minimum time value that's regarded as
being a valid time (we have to allow dates slightly before the current
time because of things like backdated cert revocations, as a rule of
thumb we allow a date up to five years in the past) and an approximation
of the current time, with the constraint that it's not after the current
date */
#define MIN_TIME_VALUE ( ( 2000 - 1970 ) * 365 * 86400L )
#define CURRENT_TIME_VALUE ( MIN_TIME_VALUE + ( 86400 * 365 * 4 ) )
#include <time.h>
time_t getTime( void );
time_t getApproxTime( void );
time_t getReliableTime( const CRYPT_HANDLE cryptHandle );
/* Hardware timer read routine used for performance evaluation */
long getTickCount( long startTime );
/****************************************************************************
* *
* Checksum/Hash Functions *
* *
****************************************************************************/
/* Hash state information. We can either call the hash function with
HASH_ALL to process an entire buffer at a time, or HASH_START/
HASH_CONTINUE/HASH_END to process it in parts */
typedef enum {
HASH_START, /* Begin hashing */
HASH_CONTINUE, /* Continue existing hashing */
HASH_END, /* Complete existing hashing */
HASH_ALL, /* One-step hash operation */
HASH_LAST /* Last valid hash option */
} HASH_STATE;
/* The hash functions are used quite a bit so we provide an internal API for
them to avoid the overhead of having to set up an encryption context
every time they're needed. These take a block of input data and hash it,
leaving the result in the output buffer. If the hashState parameter is
HASH_ALL the hashInfo parameter may be NULL, in which case the function
will use its own memory for the hashInfo */
#ifdef _BIG_WORDS
/* RIPEMD160: 24 * sizeof( long64 ) + 64 */
typedef BYTE HASHINFO[ ( 24 * 8 ) + 64 ];
#else
/* SHA-256: 26 * sizeof( long ). Note that if SHA-512 is used this
becomes 26 * sizeof( long long) instead */
typedef BYTE HASHINFO[ 26 * 4 ];
#endif /* _BIG_WORDS */
typedef void ( *HASHFUNCTION )( HASHINFO hashInfo, BYTE *outBuffer,
const BYTE *inBuffer, const int length,
const HASH_STATE hashState );
void getHashParameters( const CRYPT_ALGO_TYPE hashAlgorithm,
HASHFUNCTION *hashFunction, int *hashOutputSize );
/* Sometimes all we need is a quick-reject check, usually performed to
lighten the load before we do a full hash check. The following
function returns an integer checksum that can be used to weed out
non-matches */
int checksumData( const void *data, const int dataLength );
/****************************************************************************
* *
* Dynamic Memory Management Functions *
* *
****************************************************************************/
/* Dynamic buffer management functions. When reading variable-length
attribute data we can usually fit the data in a small, fixed-length
buffer, but occasionally we have to cope with larger data amounts that
require a dynamically-allocated buffer. The following routines manage
this process, dynamically allocating and freeing a larger buffer if
required */
#define DYNBUF_SIZE 1024
typedef struct {
void *data; /* Pointer to data */
int length;
BYTE dataBuffer[ DYNBUF_SIZE ]; /* Data buf.if size <= DYNBUF_SIZE */
} DYNBUF;
int dynCreate( DYNBUF *dynBuf, const CRYPT_HANDLE cryptHandle,
const CRYPT_ATTRIBUTE_TYPE attributeType );
void dynDestroy( DYNBUF *dynBuf );
#define dynLength( dynBuf ) ( dynBuf ).length
#define dynData( dynBuf ) ( dynBuf ).data
/* 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. To use a custom
memory pool, the caller declares a state varible of type MEMPOOL_STATE,
calls initMemPool() to initialise the pool, and then calls getMemPool()
and freeMemPool() to allocate and free memory blocks. The state pointer
is declared as a void * because to the caller it's an opaque memory block
while to the memPool routines it's structured storage */
typedef BYTE MEMPOOL_STATE[ 32 ];
void initMemPool( void *statePtr, void *memPool, const int memPoolSize );
void *getMemPool( void *statePtr, const int size );
void freeMemPool( void *statePtr, void *memblock );
/* Almost all objects require object-subtype-specific amounts of memory to
store object information. In addition some objects such as certificates
contain arbitrary numbers of arbitrary-sized bits and pieces, most of
which are quite small. To avoid having to allocate worst-case sized
blocks of memory for objects (a problem in embedded environments) or large
numbers of tiny little blocks of memory for certificate attributes, we use
variable-length structures in which the payload is stored after the
structure, with a pointer inside the structure pointing into the payload
storage. To make this easier to handle, we use macros to set up and tear
down the necessary variables */
#define DECLARE_VARSTRUCT_VARS \
int storageSize; \
BYTE storage[ 1 ]
#define initVarStruct( structure, structureType, size ) \
memset( structure, 0, sizeof( structureType ) ); \
structure->value = structure->storage; \
structure->storageSize = size
#define copyVarStruct( destStructure, srcStructure, structureType ) \
memcpy( destStructure, srcStructure, \
sizeof( structureType ) + srcStructure->storageSize ); \
destStructure->value = destStructure->storage;
#define endVarStruct( structure, structureType ) \
zeroise( structure, sizeof( structureType ) + structure->storageSize )
#define sizeofVarStruct( structure, structureType ) \
( sizeof( structureType ) + structure->storageSize )
/****************************************************************************
* *
* Randomness Functions *
* *
****************************************************************************/
/* In order to make it easier to add lots of arbitrary-sized random data
values, we make the following functions available to the polling code to
implement a clustered-write mechanism for small data quantities. These
add an integer, long, or (short) string value to a buffer and send it
through to the system device when the buffer is full. Using the
intermediate buffer ensures that we don't have to send a message to the
device for every bit of data added
The caller declares a state variable of type RANDOM_STATE, calls
initRandomData() to initialise it, calls addRandomData() for each
consecutive piece of data to add to the buffer, and finally calls
endRandomData() to flush the data through to the system device. The
state pointer is declared as a void * because to the caller it's an
opaque memory block while to the randomData routines it's structured
storage */
typedef BYTE RANDOM_STATE[ 128 ];
void initRandomData( void *statePtr, void *buffer, const int maxSize );
int addRandomData( void *statePtr, const void *value,
const int valueLength );
int addRandomLong( void *statePtr, const long value );
int endRandomData( void *statePtr, const int quality );
/* We also provide an addRandomValue() to make it easier to add function
return values for getXYZ()-style system calls that return system info as
their return value, for which we can't pass an address to addRandomData()
unless we copy it to a temporary var first */
#define addRandomValue( statePtr, value ) \
addRandomLong( statePtr, ( long ) value )
/****************************************************************************
* *
* Envelope Management 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 );
int envelopeUnwrap( const void *inData, const int inDataLength,
void *outData, int *outDataLength,
const int outDataMaxLength,
const CRYPT_CONTEXT iDecryptKey );
int envelopeSign( const void *inData, const int inDataLength,
void *outData, int *outDataLength,
const int outDataMaxLength,
const CRYPT_CONTENT_TYPE contentType,
const CRYPT_CONTEXT iSigKey,
const CRYPT_CERTIFICATE iCmsAttributes );
int envelopeSigCheck( const void *inData, const int inDataLength,
void *outData, int *outDataLength,
const int outDataMaxLength,
const CRYPT_CONTEXT iSigCheckKey,
int *sigResult, CRYPT_CERTIFICATE *iSigningCert,
CRYPT_CERTIFICATE *iCmsAttributes );
#endif /* _INTAPI_DEFINED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -