⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpber.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:

	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 + -