📄 cert_util.c
字号:
/*******************************************************************
*
* This file was generated by TIS/ASN1COMP Ver. 4.2, an ASN.1 compiler.
* TIS/ASN1COMP is Copyright (c) 1998, TIS Labs at Network Associates, Inc.
*
* This file was AUTOMATICALLY GENERATED on Mon May 17 09:25:53 1999
*
******************************************************************/
/**********************************************************************
* cert_util.c
*
* Utility routines for ASN.1 coding
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "cert_util.h"
#ifdef PKITRACE
int PKITRACE_LEVEL = 0;
#endif
/***********************************************************************
* PKIErrorHalt
*
* a dummy routine, called if error, on which one can halt/
*************************************************************************/
void PKIErrorHalt(int x)
{
(void)x; /* not usted */
return;
} /* err_halt */
/**********************************************************************
* Default mem. mgmt callbacks
*
* These are defaults that the user can use if desired, or use them
* as models for your own set of memory mgmt. callbacks.
***********************************************************************/
/* default memory allocator */
static void *
PKIDefaultMemoryAllocationProc(
PKIMemoryMgr *mgr,
size_t requestSize)
{
(void)mgr;
return ( malloc(requestSize) );
} /* PKIDefaultMemoryAllocationProc */
/* default memory reallocator */
static int
PKIDefaultMemoryReallocationProc(
PKIMemoryMgr *mgr,
void **allocation,
size_t newAllocationSize)
{
int err;
void *newPtr = NULL;
void *oldPtr = *allocation;
(void)mgr;
newPtr = realloc(oldPtr, newAllocationSize);
if (newPtr == NULL) {
err = PKIErrOutOfMemory;
}
else {
err = 0;
*allocation = newPtr;
}
return err;
} /* PKIMemoryMgrReallocationProc */
/* default memory deallocation routine */
static int
PKIDefaultMemoryDeallocationProc(
PKIMemoryMgr *mgr,
void *allocation)
{
(void)mgr;
free(allocation);
return 0;
} /* PKIMemoryMgrDeallocationProc */
/* the default PKIMemoryMgr structure for the user */
PKIMemoryMgr PKIdefaultMemoryMgrStruct = {
NULL,
PKIDefaultMemoryAllocationProc,
PKIDefaultMemoryReallocationProc,
PKIDefaultMemoryDeallocationProc
};
/***************************************************************************
* PKICompareElems
* A routine to provide to the qsort routine for comparing two
* <prefix>PrimVariableBlock blocks. This is used by the pack
* routines for SET OF structures. This assumes the compare should
* use the length of the longer element provided and for SET OF, then* provided elements should have 0's at the ends of shorter elements.
****************************************************************************/
int PKICompareElems(const void *a, const void *b)
{
int length;
PKIVariableBlock *locala = (PKIVariableBlock *)a;
PKIVariableBlock *localb = (PKIVariableBlock *)b;
if (locala->len > localb->len)
length = locala->len;
else
length = localb->len;
return(memcmp(locala->val, localb->val, length));
} /* PKICompareElems */
/************************************************************************
* PKILengthSize -- for scanning the length of a basic integer
* for the ASN.1 length field after the tag.
*************************************************************************/
size_t PKILengthSize(size_t x)
{
if ( x <= 127 ) return 1;
else if ( x < 0x100 ) return 2;
else if ( x < 0x10000 ) return 3;
else if ( x < 0x1000000 ) return 4;
else return 5;
} /* LengthSize */
/************************************************************************
* Tagged -- compute and return the size of a tagged ASN.1 object
* whose size without the tag would be (inner).
*************************************************************************/
size_t PKITagged(size_t inner, int seqlike )
{
if ( inner == 0 && ! seqlike )
return (0);
return ( 1 + inner + PKILengthSize(inner) );
} /* Tagged */
/************************************************************************
* PKIPutByte -- put an ASN.1 type byte to op
*************************************************************************/
size_t PKIPutByte( unsigned char *buf, unsigned char byte )
{
*buf = byte;
return 1;
} /* PKIPutByte */
/************************************************************************
* PKIPutLength -- put a length field to opp
************************************************************************/
size_t PKIPutLength( unsigned char *buf, size_t length )
{
unsigned char *bufptr = buf;
size_t size = PKILengthSize(length) - 1;
unsigned char bytes[4] ;
unsigned char *bp = &(bytes[3]) ; /* pointer for unpacking */
switch (size) {
case 4: *(bp--) = (unsigned char)length & 0xff ; length >>= 8 ;
case 3: *(bp--) = (unsigned char)length & 0xff ; length >>= 8 ;
case 2: *(bp--) = (unsigned char)length & 0xff ; length >>= 8 ;
case 1: *(bp--) = (unsigned char)length & 0xff ; length >>= 8 ;
default: /* fall through */ ;
} /* turn x into bytes */
/* only need one byte for length */
if (size == 0)
*(bufptr++) = (unsigned char)(length & 0x7f);
/* otherwise first byte is number of bytes needed for size */
else
*(bufptr++) = (unsigned char)(0x80 | size) ;
size = 4 - size; /* as an index into bytes[] */
while (size < 4) *(bufptr++) = bytes[size++] ;
/* return the number of bytes used */
return (size_t)(bufptr-buf);
} /* PKIPutLength */
/************************************************************************
* PKIGetByte -- get an ASN.1 type byte to op
*************************************************************************/
size_t PKIGetByte(const unsigned char *buf, unsigned char *byte)
{
*byte = *buf;
return 1;
} /* PKIGetByte */
/************************************************************************
* PKIGetLength -- fetch a length field from opp and return it
* If this is indefinite length, then return -1 for the length.
*************************************************************************/
size_t PKIGetLength(const unsigned char *buf, size_t *length)
{
size_t bytesused;
unsigned long x ;
unsigned char c ;
c = *buf; /* get the control byte (or length) */
bytesused = 1;
if (c == 0x80) { /* this is indefinite length */
*length = -1;
return bytesused;
}
if ((c & 0x80) == 0) { /* have the length already */
*length = (size_t)c; /* note the byte we used */
PKITRACE_PRINT_LENGTH(c);
return bytesused; /* return the length */
} /* if */
c &= 0x7f ; /* get the number of bytes of length */
x = 0 ; /* clear x */
while ((c--) > 0) {
x <<= 8 ; /* shift up the word */
x |= (unsigned long)*(buf + bytesused); /* gather the next byte */
bytesused++;
} /* pack as integer */
PKITRACE_PRINT_LENGTH((int)x);
*length = (size_t)x; /* note the bytes used */
return bytesused; /* return the length */
} /* PKIGetLength */
/************************************************************************
* PKIPutTag
*
* Put a tag field (tag + length) to the output block
*************************************************************************/
size_t PKIPutTag( unsigned char *buf, unsigned char tagbyte, size_t length )
{
size_t bytesused;
bytesused = PKIPutByte(buf, tagbyte);
bytesused += PKIPutLength(buf+bytesused, length);
return bytesused;
} /* PKIPutTag */
/************************************************************************
* PKITakeTag
*
* Get a tag field from the input block and return its length
*************************************************************************/
size_t PKITakeTag(const unsigned char *buf, unsigned char tag, size_t *length)
{
size_t bytesused = 0;
*length = 0;
if (buf == NULL) return 0;
if (*buf != tag) return 0;
/* have that tag */
bytesused = 1; /* consume the tag byte */
bytesused += PKIGetLength(buf+bytesused, length);
return bytesused;
} /* PKITakeTag */
/************************************************************************
* Basic variable block routines
*************************************************************************/
void *PKINewVariableBlock(PKICONTEXT *ctx)
{
PKIVariableBlock *block = NULL ;
if (ctx == NULL)
return NULL;
block = (PKIVariableBlock *) PKIAlloc(ctx->memMgr,
sizeof(PKIVariableBlock) );
if (block != NULL)
memset(block, 0, sizeof(PKIVariableBlock)) ;
return (void *)block;
} /* PKINewVariableBlock */
size_t PKISizeofVariableBlock(PKICONTEXT *ctx,
PKIVariableBlock *block,
int outerSizeFlag)
{
(void)ctx; /* for future use */
return PKISizeofVariableBlockInternal(block, outerSizeFlag, PKIFALSE);
}
/*****
*
* internal PKISizeofVariableBlock
*
* This internal routine handles the case where there is an
* explicitly tagged field in a constructed ASN block. The final length
* returned will be increased by the explicit tag bits (using the tagged()
* routine) only if the previous calculations don't result in zero.
*
* It is assumed that outerSizeFlag will not be FALSE when expTaggedSize
* is TRUE. This is handled by the generated code. It does not call
* _sizeof with this case. Also, the wrapper routine above calls this
* routine with expTaggedSize as FALSE. So, this routine doesn't do any
* error checking in that respect.
*
*****/
size_t PKISizeofVariableBlockInternal(
PKIVariableBlock *block,
int outerSizeFlag,
int expTaggedSize)
{
size_t length;
if (block == NULL)
return (0);
length = (size_t)block->len;
if (outerSizeFlag == PKITRUE)
length = length + 1 + PKILengthSize(block->len);
if (expTaggedSize == PKITRUE)
length = PKITagged(length, 0);
return length;
} /* PKISizeofVariableBlockInternal */
void PKIDropInPlaceVariableBlock(PKICONTEXT *ctx,
PKIVariableBlock *f )
{
if (ctx == NULL)
return;
if (f != NULL && f->val != NULL) {
PKIFree(ctx->memMgr, f->val);
f->val = NULL;
}
} /* PKIDropInPlaceVariableBlock */
void PKIFreeVariableBlock(PKICONTEXT *ctx,
PKIVariableBlock *f)
{
if (ctx == NULL)
return;
PKIDropInPlaceVariableBlock(ctx, f);
if (f != NULL)
PKIFree(ctx->memMgr, f);
return;
} /* PKIFreeVariableBlock */
/************************************************************************
* pack and unpack -- taking block type as a parameter/
*************************************************************************/
static size_t UnpkInPlaceSegments(
PKICONTEXT *ctx,
int indefFlag, /* is this an indefinite length block or not? */
unsigned char exptag, /* my expected block tag */
PKIVariableBlock *asnblock, /* output block */
const unsigned char *buf, /* loc of input pointer */
size_t buflen, /* max end of my region */
int *erret) /* error return location */
{
size_t bytesused = 0;
size_t datasize;
/* validity of ctx and erret checked in UnpkInPlaceVariableBlock */
if (buf == NULL) {
PKIERR(PKIErrUnpackNoBlockPtr);
return 0;
}
/* validity of asnblock checked in UnpkInPlaceVariableBlock */
asnblock->val = NULL;
asnblock->len = 0;
/* while there are segments */
while (1) {
/* For indef length end-of-contents is 0x00 0x00 and we
have to eat those two bytes, otherwise we see if we've
used up all the available data yet */
if ( indefFlag == 1 &&
(*(buf+bytesused) == 0x00 && *(buf+bytesused+1) == 0x00) ) {
bytesused += 2;
break;
}
else if (indefFlag == 0 && bytesused == buflen)
break;
if (*buf != exptag) {
PKIERR(PKIErrUnpackInvalidEncoding);
return 0;
}
bytesused++; /* skip the tag byte */
datasize = 0;
bytesused += PKIGetLength(buf+bytesused, &datasize);
/* no nested indef lengths for string types */
if ((int)datasize == -1) {
PKIERR(PKIErrUnpackInvalidEncoding);
return 0;
}
if (bytesused + datasize > buflen) {
PKIERR(PKIErrUnpackOverrun); /* note this error */
return 0;
}
if (datasize == 0)
continue;
PKIRealloc(ctx->memMgr,
(void **)&asnblock->val, asnblock->len+datasize);
if (asnblock->val == NULL) {
PKIERR(PKIErrOutOfMemory);
return 0;
}
memcpy(asnblock->val + asnblock->len,
buf+bytesused, datasize);
asnblock->len += datasize;
bytesused += datasize;
} /* while there are segments */
return bytesused;
} /* UnpkInPlaceSegments */
static size_t UnpkInPlaceVariableBlock(
PKICONTEXT *ctx,
unsigned char exptag, /* my expected block tag */
const char *name, /* my block name */
unsigned char tag, /* my real tag */
PKIVariableBlock *asnblock, /* output block */
const unsigned char *buf, /* loc of input pointer */
size_t buflen, /* max end of my region */
int *erret) /* error return location */
{
size_t bytesused;
size_t datasize;
int constructed = 0;
int indef = 0;
PKITRACE_name(name);
PKITRACE_PRINT_FM(exptag, tag, name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -