📄 asn1.h
字号:
/****************************************************************************
* *
* ASN.1 Constants and Structures *
* Copyright Peter Gutmann 1992-2003 *
* *
****************************************************************************/
#ifndef _ASN1_DEFINED
#define _ASN1_DEFINED
#include <time.h>
#if defined( INC_ALL )
#include "stream.h"
#include "ber.h"
#elif defined( INC_CHILD )
#include "../io/stream.h"
#include "ber.h"
#else
#include "io/stream.h"
#include "misc/ber.h"
#endif /* Compiler-specific includes */
/****************************************************************************
* *
* ASN.1 Constants and Macros *
* *
****************************************************************************/
/* Special-case tags. If DEFAULT_TAG is given the basic type (e.g. INTEGER,
ENUMERATED) is used, otherwise the value is used as a context-specific
tag. If NO_TAG is given, processing of the tag is skipped. If ANY_TAG
is given, the tag is ignored */
#define DEFAULT_TAG -1
#define NO_TAG -2
#define ANY_TAG -3
/* The maximum allowed size for an (encoded) object identifier */
#define MAX_OID_SIZE 32
/* Macros and functions to work with indefinite-length tags. The only ones
used are SEQUENCE and [0] (for the outer encapsulation) and OCTET STRING
(for the data itself) */
#define writeOctetStringIndef( stream ) swrite( stream, BER_OCTETSTRING_INDEF, 2 )
#define writeSequenceIndef( stream ) swrite( stream, BER_SEQUENCE_INDEF, 2 )
#define writeSetIndef( stream ) swrite( stream, BER_SET_INDEF, 2 )
#define writeCtag0Indef( stream ) swrite( stream, BER_CTAG0_INDEF, 2 )
#define writeEndIndef( stream ) swrite( stream, BER_END_INDEF, 2 )
int checkEOC( STREAM *stream );
/* The use of the preprocessor to hide function details for the read/read-
tag/read-data variants screws up the use of autocomplete in the VC++
editor, Microsoft get around this in some unknown fashion for Win32 API
functions by including a custom debug database Win32.ncb in the VC98
directory, but it's not known how they generate this. To fix this, we
prototype the following (nonexistent) functions when we're building with
VC++ */
#ifdef _MSC_VER
int readRawObject( STREAM *stream, BYTE *buffer, int *bufferLength,
const int maxLength );
int readRawObjectData( STREAM *stream, BYTE *buffer, int *bufferLength,
const int maxLength );
int writeRawObject( STREAM *stream, const void *object, const int size );
int sizeofOID( const BYTE *oid );
int writeOID( STREAM *stream, const BYTE *oid );
int sizeofInteger( const void *integer, const int integerLength );
int readInteger( STREAM *stream, BYTE *integer, int *integerLength,
const int maxLength );
int readIntegerData( STREAM *stream, BYTE *integer, int *integerLength,
const int maxLength );
int sizeofBignum( const void *bignum );
int writeBignum( STREAM *stream, const void *bignum );
int writeBignumData( STREAM *stream, const void *bignum );
int sizeofShortInteger( const int value );
int readShortInteger( STREAM *stream, long *value );
int readShortIntegerData( STREAM *stream, long *value );
int sizeofEnumerated( const int value );
int readEnumerated( STREAM *stream, int *enumeration );
int readEnumeratedData( STREAM *stream, int *enumeration );
int sizeofBoolean( void );
int readBoolean( STREAM *stream, BOOLEAN *boolean );
int readBooleanData( STREAM *stream, BOOLEAN *boolean );
int sizeofNull( void );
int readNull( STREAM *stream );
int readNullData( STREAM *stream );
int readOctetString( STREAM *stream, BYTE *string, int *stringLength,
const int maxLength );
int readOctetStringData( STREAM *stream, BYTE *string, int *stringLength,
const int maxLength );
int sizeofBitString( const int value );
int readBitString( STREAM *stream, int *bitString );
int readBitStringData( STREAM *stream, int *bitString );
int sizeofUTCTime( void );
int readUTCTime( STREAM *stream, time_t *timeVal );
int readUTCTimeData( STREAM *stream, time_t *timeVal );
int sizeofGeneralizedTime( void );
int readGeneralizedTime( STREAM *stream, time_t *timeVal );
int readGeneralizedTimeData( STREAM *stream, time_t *timeVal );
#endif /* VC++ */
/****************************************************************************
* *
* ASN.1 Function Prototypes *
* *
****************************************************************************/
/* Determine the size of an object once it's wrapped up with a tag and
length */
long sizeofObject( const long length );
/* Generalized ASN.1 type manipulation routines. readRawObject() reads a
complete object (including tag and length data) while readUniversal()
just skips it */
int readUniversalData( STREAM *stream );
int readUniversal( STREAM *stream );
int readRawObjectTag( STREAM *stream, BYTE *buffer, int *bufferLength,
const int maxLength, const int tag );
#define readRawObject( stream, buffer, bufferLength, maxLength, tag ) \
readRawObjectTag( stream, buffer, bufferLength, maxLength, tag )
#define readRawObjectData( stream, buffer, bufferLength, maxLength ) \
readRawObjectTag( stream, buffer, bufferLength, maxLength, NO_TAG )
#define writeRawObject( stream, object, size ) \
swrite( stream, object, size )
/* Routines for handling OBJECT IDENTIFIERS. The sizeof() macro determines
the length of an encoded object identifier as tag + length + value.
Write OID routines equivalent to the ones for other ASN.1 types don't
exist since OIDs are always read and written as a blob with sread()/
swrite(). OIDs are never tagged so we don't need any special-case
handling for tags.
When there's a choice of possible OIDs, the list of OID values and
corresponding selection IDs is provided in an OID_INFO structure (we also
provide a shortcut readFixedOID() function when there's only a single OID
that's valid at that point). The read OID value is checked against each
OID in the OID_INFO list, if a match is found the selectionID is returned.
The OID_INFO includes a pointer to further user-supplied information
related to this OID that may be used by the user, set when the OID list
is initialised. For example it could point to OID-specific handlers for
the data. When the caller needs to work with the extraInfo field, it's
necessary to return the complete OID_INFO entry rather than just the
selection ID, which is done by the ..Ex() form of the function */
typedef struct {
const BYTE *oid; /* OID */
const int selectionID; /* Value to return for this OID */
const void *extraInfo; /* Additional info for this selection */
} OID_INFO;
#define sizeofOID( oid ) ( 1 + 1 + ( int ) oid[ 1 ] )
int readOID( STREAM *stream, const OID_INFO *oidSelection,
int *selectionID );
int readOIDEx( STREAM *stream, const OID_INFO *oidSelection,
const OID_INFO **oidSelectionValue );
int readFixedOID( STREAM *stream, const BYTE *oid );
#define writeOID( stream, oid ) \
swrite( ( stream ), ( oid ), sizeofOID( oid ) )
/* Routines for handling large integers. When we're writing these we can't
use sizeofObject() directly because the internal representation is
unsigned whereas the encoded form is signed. The following macro performs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -