📄 pgpber.c
字号:
for( i = 0; fmt[i] != '\0'; i++ )
{
switch( fmt[i] )
{
case kPGPberFormatSpecifier_Boolean:
boolArg = (PGPBoolean) va_arg( argList, PGPInt32 );
if( tag == kPGPberType_None )
tag = kPGPberType_Boolean;
/*
* Since the boolean will only be one byte long, we can pretend
* it's just an integer with a different tag (the boolean tag).
*/
err = pgpBERInsertInt( ber, boolArg, tag ); CKERR;
break;
case kPGPberFormatSpecifier_Int:
intArg = va_arg( argList, PGPInt32 );
if( tag == kPGPberType_None )
tag = kPGPberType_Int;
err = pgpBERInsertInt( ber, intArg, tag ); CKERR;
break;
case kPGPberFormatSpecifier_Octetstring:
octetStringArg = va_arg( argList, PGPByte * );
intArg = va_arg( argList, PGPSize );
if( tag == kPGPberType_None )
tag = kPGPberType_Octetstring;
err = pgpBERInsertOctetstring( ber, octetStringArg, intArg, tag ); CKERR;
break;
case kPGPberFormatSpecifier_String:
stringArg = va_arg( argList, char * );
if( tag == kPGPberType_None )
tag = kPGPberType_Octetstring;
err = pgpBERInsertString( ber, stringArg, tag ); CKERR;
break;
case kPGPberFormatSpecifier_StringVector:
stringVectorArg = va_arg( argList, char ** );
if( IsNull( stringVectorArg ) )
break;
if( tag == kPGPberType_None )
tag = kPGPberType_Octetstring;
for( j = 0; stringVectorArg[j] != NULL; j++ )
{
err = pgpBERInsertString( ber, stringVectorArg[j], tag );
CKERR;
}
break;
case kPGPberFormatSpecifier_BERVector:
berVectorArg = va_arg( argList, PGPberValue ** );
if( tag == kPGPberType_None )
tag = kPGPberType_Octetstring;
for( j = 0; berVectorArg[j] != NULL; j++ )
{
err = pgpBERInsertOctetstring( ber,
berVectorArg[j]->value,
berVectorArg[j]->length,
tag ); CKERR;
}
break;
case kPGPberFormatSpecifier_NULL:
if( tag == kPGPberType_None )
tag = kPGPberType_NULL;
err = pgpBERInsertNULL( ber, tag ); CKERR;
break;
case kPGPberFormatSpecifier_Enumeration:
intArg = va_arg( argList, PGPInt32 );
if( tag == kPGPberType_None )
tag = kPGPberType_Enumeration;
err = pgpBERInsertInt( ber, intArg, tag ); CKERR;
break;
case kPGPberFormatSpecifier_Tag:
tag = va_arg( argList, PGPUInt32 );
clearTag = FALSE;
break;
case kPGPberFormatSpecifier_BeginSequence:
if( tag == kPGPberType_None )
tag = kPGPberType_Sequence;
err = pgpBERBeginSequence( ber, tag ); CKERR;
break;
case kPGPberFormatSpecifier_EndSequence:
err = pgpBEREndSequence( ber ); CKERR;
break;
case kPGPberFormatSpecifier_BeginSet:
if( tag == kPGPberType_None )
tag = kPGPberType_Set;
err = pgpBERBeginSet( ber, tag ); CKERR;
break;
case kPGPberFormatSpecifier_EndSet:
err = pgpBEREndSet( ber ); CKERR;
break;
default:
return kPGPError_BadParams;
break;
}
/* If clearTag is set, we need to use a custom tag for the next
* element in the BER encoded string. After we run through the above
* switch statement again, we have saved away the custom tag or used
* it, and need to reset tag to the default. */
if( clearTag )
tag = kPGPberType_None;
else
clearTag = TRUE;
}
va_end( argList );
error:
return err;
}
/****************************************************************************
* BER decoding routines *
****************************************************************************/
PGPInt32
pgpReceiveLen(
PGPSocketRef sock,
void * buffer,
PGPUInt32 bufferSize )
{
PGPUInt32 bytesRead = 0;
PGPInt32 returnValue = 0;
PGPValidatePtr( buffer );
while( bytesRead < bufferSize )
{
returnValue = PGPReceive( sock, ( (PGPByte *) buffer ) + bytesRead,
bufferSize - bytesRead,
kPGPReceiveFlagNone );
if( returnValue <= 0 )
break;
bytesRead += returnValue;
}
return bytesRead;
}
PGPError
pgpBERReadTag(
PGPByte * s,
PGPberType * tag,
PGPSize * tagLength)
{
PGPberType netTag = kPGPberType_None;
PGPByte c = 0;
PGPUInt32 i = 0;
PGPValidatePtr( s );
PGPValidatePtr( tag );
PGPValidatePtr( tagLength );
if( ( s[0] & kPGPberMask_BigTag ) == kPGPberMask_BigTag )
{
netTag = (PGPberType)0;
i = 0;
do
{
i++;
c = s[i] & ~kPGPberMask_MoreTag;
netTag >>= 8;
pgpCopyMemory( &c, (PGPByte *) &netTag + ( sizeof( PGPberType ) - 1 ), 1 );
} while( s[i] & kPGPberMask_MoreTag );
*tag = PGPNetToHostLong( netTag );
*tagLength = i + 1;
}
else
{
*tag = (PGPberType)s[0];
*tagLength = 1;
}
return kPGPError_NoErr;
}
PGPError
pgpBERReadUInt(
PGPByte * s,
PGPSize length,
PGPUInt32 * outInt )
{
PGPError err = kPGPError_NoErr;
PGPValidatePtr( s );
PGPValidatePtr( outInt );
*outInt = 0;
switch( length )
{
case 1:
*outInt = (PGPInt32) s[0];
break;
case 2:
*outInt = (PGPUInt32) PGPEndianToUInt16( kPGPBigEndian, s );
break;
case 3:
*outInt = (PGPUInt32) PGPEndianToUInt16( kPGPBigEndian, s );
*outInt <<= 8;
*outInt |= s[2];
break;
case 4:
*outInt = PGPEndianToUInt32( kPGPBigEndian, s );
break;
default:
err = kPGPError_BadParams;
*outInt = 0;
break;
}
return err;
}
PGPError
pgpBERReadLength(
PGPByte * s,
PGPSize * length ,
PGPSize * lengthOfLength )
{
PGPByte byteLen = 0;
PGPByte lengthString[sizeof( PGPSize )];
PGPError err = kPGPError_NoErr;
PGPUInt32 i = 0;
PGPValidatePtr( s );
PGPValidatePtr( length );
PGPValidatePtr( lengthOfLength );
byteLen = s[0];
if( byteLen & kPGPberMask_BigLength )
{
*lengthOfLength = byteLen & ( ~kPGPberMask_BigLength );
if( *lengthOfLength > 4 )
{
err = kPGPError_CorruptData;
goto error;
}
pgpCopyMemory( s + 1, lengthString, *lengthOfLength );
err = pgpBERReadUInt( lengthString, *lengthOfLength, (PGPUInt32 *)length ); CKERR;
/* Add the length of byteLen */
(*lengthOfLength)++;
}
else if( byteLen == kPGPberMask_IndefLength )
{
/*
* String of indefinite length. This means that the length
* is given as 0 bytes, and we need to read the string until we
* find the end-of-contents octets (two zero octets).
*/
pgpAssert( 0 ); /* Untested */
err = kPGPError_CorruptData;
goto error;
for( i = 1; ( s[i] != '\0' ) || ( s[i+1] != '\0' ); i++ )
; /* NULL */
*lengthOfLength = 1;
*length = i + 1;
}
else
{
*lengthOfLength = 1;
*length = byteLen;
}
error:
return err;
}
PGPError
PGPberReadResponse(
PGPberElementRef ber,
PGPSocketRef sock )
{
PGPByte byteTag = (PGPByte) kPGPberType_None;
PGPByte byteLen = 0;
PGPSize len = 0;
PGPSize lengthOfLength = 0;
PGPSize prefixLength = 0;
PGPError err = kPGPError_NoErr;
PGPByte s[16];
PGPValidateBERElementRef( ber );
if( pgpReceiveLen( sock, &byteTag, 1 ) != 1 )
{
err = PGPGetLastSocketsError();
goto error;
}
if( ( byteTag & kPGPberMask_BigTag ) == kPGPberMask_BigTag )
{
/* Untested */
pgpAssert( 0 );
err = kPGPError_CorruptData;
goto error;
/*
PGPUInt32 netTag = kPGPberType_None;
PGPSize tagLength = 0;
PGPByte c = 0;
PGPUInt32 i = 0;
netTag = 0;
s[0] = byteTag;
i = 1;
do
{
if( pgpReceiveLen( sock, &c, 1 ) != 1 )
{
err = PGPGetLastSocketsError();
goto error;
}
s[i++] = c;
} while( c & kPGPberMask_MoreTag );
pgpBERReadTag( s, (PGPberType *)&tag, &tagLength );
prefixLength += tagLength;
*/
}
else
prefixLength++;
if( pgpReceiveLen( sock, &byteLen, 1 ) != 1 )
{
err = PGPGetLastSocketsError();
goto error;
}
prefixLength++;
if( byteLen & kPGPberMask_BigLength )
{
lengthOfLength = byteLen & ( ~kPGPberMask_BigLength );
if( lengthOfLength > sizeof( s ) )
{
err = kPGPError_BadParams;
goto error;
}
if( pgpReceiveLen( sock, s, (PGPUInt32) lengthOfLength ) !=
(PGPInt32) lengthOfLength )
{
err = PGPGetLastSocketsError();
goto error;
}
err = pgpBERReadUInt( s, lengthOfLength, (PGPUInt32 *)&len ); CKERR;
prefixLength += lengthOfLength;
}
else
{
lengthOfLength = 1;
len = byteLen;
}
ber->encoding = PGPNewData( ber->memMgr, len + prefixLength,
kPGPMemoryMgrFlags_Clear );
if( IsNull( ber->encoding ) )
{
err = kPGPError_OutOfMemory;
goto error;
}
/*pgpCopyMemory( &byteTag, ber->encoding, 1 ); */
ber->encoding[0] = byteTag;
if( byteLen & kPGPberMask_BigLength )
{
pgpCopyMemory( &byteLen, ber->encoding + 1, 1 );
pgpCopyMemory( s, ber->encoding + 2, lengthOfLength );
}
else
pgpCopyMemory( &byteLen, ber->encoding + 1, 1 );
if( pgpReceiveLen( sock, ber->encoding + prefixLength, (PGPInt32) len )
!= (PGPInt32) len )
{
err = PGPGetLastSocketsError();
goto error;
}
ber->length = len + prefixLength;
goto done;
error:
if( IsntNull( ber ) )
{
if( IsntNull( ber->encoding ) )
{
(void) PGPFreeData( ber->encoding );
ber->encoding = NULL;
}
}
if( IsntPGPError( err ) )
err = kPGPError_UnknownError;
done:
return err;
}
PGPError
PGPberSetData(
PGPberElementRef ber,
PGPByte * data,
PGPSize len )
{
PGPError err = kPGPError_NoErr;
PGPValidateBERElementRef( ber );
ber->encoding = PGPNewData( ber->memMgr, len, kPGPMemoryMgrFlags_Clear );
if( IsNull( ber->encoding ) )
{
err = kPGPError_OutOfMemory;
goto error;
}
pgpCopyMemory( data, ber->encoding, len );
ber->length = len;
goto done;
error:
if( IsntNull( ber->encoding ) )
{
(void) PGPFreeData( ber->encoding );
ber->encoding = NULL;
}
if( IsntPGPError( err ) )
err = kPGPError_UnknownError;
done:
return err;
}
PGPError
pgpBERReadInt(
PGPByte * s,
PGPSize length,
PGPInt32 * outInt )
{
PGPError err = kPGPError_NoErr;
PGPUInt32 i = 0;
PGPInt32 sign = 0;
PGPValidatePtr( s );
PGPValidatePtr( outInt );
err = pgpBERReadUInt( s, length, (PGPUInt32 *) outInt ); CKERR;
sign = *outInt & ( 0x80 << ( ( i - 1 ) * 8 ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -