Пример #1
0
static int readRDNcomponent( INOUT STREAM *stream, 
							 INOUT DN_COMPONENT **dnComponentListPtrPtr,
							 IN_LENGTH_SHORT const int rdnDataLeft )
	{	
	CRYPT_ERRTYPE_TYPE dummy;
	BYTE stringBuffer[ MAX_ATTRIBUTE_SIZE + 8 ];
	void *value;
	const int rdnStart = stell( stream );
	int type, valueLength, valueStringType, stringTag;
	int flags = DN_FLAG_NOCHECK, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( dnComponentListPtrPtr, sizeof( DN_COMPONENT * ) ) );

	REQUIRES( rdnDataLeft > 0 && rdnDataLeft < MAX_INTLENGTH_SHORT );
	REQUIRES( rdnStart > 0 && rdnStart < MAX_INTLENGTH_SHORT );

	/* Read the type information for this AVA */
	status = readAVA( stream, &type, &valueLength, &stringTag );
	if( cryptStatusError( status ) )
		return( status );
	if( valueLength <= 0 )
		{
		/* Skip broken AVAs with zero-length strings */
		return( CRYPT_OK );
		}
	status = sMemGetDataBlock( stream, &value, valueLength );
	if( cryptStatusOK( status ) )
		status = sSkip( stream, valueLength );
	if( cryptStatusError( status ) )
		return( status );
	ANALYSER_HINT( value != NULL );

	/* If there's room for another AVA, mark this one as being continued.  The
	   +10 value is the minimum length for an AVA: SEQUENCE { OID, value } 
	   (2-bytes SEQUENCE + 5 bytes OID + 2 bytes (tag + length) + 1 byte min-
	   length data).  We don't do a simple =/!= check to get around incorrectly 
	   encoded lengths */
	if( rdnDataLeft >= ( stell( stream ) - rdnStart ) + 10 )
		flags |= DN_FLAG_CONTINUED;

	/* Convert the string into the local character set */
	status = copyFromAsn1String( stringBuffer, MAX_ATTRIBUTE_SIZE, 
								 &valueLength, &valueStringType, value, 
								 valueLength, stringTag );
	if( cryptStatusError( status ) )
		return( status );

	/* Add the DN component to the DN.  If we hit a non-memory related error
	   we turn it into a generic CRYPT_ERROR_BADDATA error since the other
	   codes are somewhat too specific for this case, something like 
	   CRYPT_ERROR_INITED or an arg error isn't too useful for the caller */
	status = insertDNstring( dnComponentListPtrPtr, type, stringBuffer, 
							 valueLength, valueStringType, flags, &dummy );
	return( ( cryptStatusError( status ) && status != CRYPT_ERROR_MEMORY ) ? \
			CRYPT_ERROR_BADDATA : status );
	}
Пример #2
0
static int readRDNcomponent( INOUT STREAM *stream, 
							 INOUT DN_COMPONENT **dnComponentListPtrPtr,
							 IN_LENGTH_SHORT const int rdnDataLeft )
	{	
	CRYPT_ERRTYPE_TYPE dummy;
	BYTE stringBuffer[ MAX_ATTRIBUTE_SIZE + 8 ];
	void *value;
	const int rdnStart = stell( stream );
	int type, valueLength, valueStringType, stringTag;
	int flags = DN_FLAG_NOCHECK, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( dnComponentListPtrPtr, sizeof( DN_COMPONENT * ) ) );

	REQUIRES( rdnDataLeft > 0 && rdnDataLeft < MAX_INTLENGTH_SHORT );
	REQUIRES( rdnStart > 0 && rdnStart < MAX_INTLENGTH_SHORT );

	/* Read the type information for this AVA */
	status = readAVA( stream, &type, &valueLength, &stringTag );
	if( cryptStatusError( status ) )
		{
		/* If this is an unrecognised AVA, don't try and process it (the
		   content will already have been skipped in readAVA()) */
		if( status == OK_SPECIAL )
			return( CRYPT_OK );

		return( status );
		}

	/* Make sure that the string is a valid type for a DirectoryString.  We 
	   don't allow Universal strings since no-one in their right mind uses
	   those.
	   
	   Alongside DirectoryString values we also allow IA5Strings, from the
	   practice of stuffing email addresses into DNs */
	if( stringTag != BER_STRING_PRINTABLE && stringTag != BER_STRING_T61 && \
		stringTag != BER_STRING_BMP && stringTag != BER_STRING_UTF8 && \
		stringTag != BER_STRING_IA5 )
		return( CRYPT_ERROR_BADDATA );

	/* Skip broken AVAs with zero-length strings */
	if( valueLength <= 0 )
		return( CRYPT_OK );

	/* Record the string contents, avoiding moving it into a buffer */
	status = sMemGetDataBlock( stream, &value, valueLength );
	if( cryptStatusOK( status ) )
		status = sSkip( stream, valueLength, MAX_INTLENGTH_SHORT );
	if( cryptStatusError( status ) )
		return( status );
	ANALYSER_HINT( value != NULL );

	/* If there's room for another AVA, mark this one as being continued.  The
	   +10 value is the minimum length for an AVA: SEQUENCE { OID, value } 
	   (2-bytes SEQUENCE + 5 bytes OID + 2 bytes (tag + length) + 1 byte min-
	   length data).  We don't do a simple =/!= check to get around incorrectly 
	   encoded lengths */
	if( rdnDataLeft >= ( stell( stream ) - rdnStart ) + 10 )
		flags |= DN_FLAG_CONTINUED;

	/* Convert the string into the local character set */
	status = copyFromAsn1String( stringBuffer, MAX_ATTRIBUTE_SIZE, 
								 &valueLength, &valueStringType, value, 
								 valueLength, stringTag );
	if( cryptStatusError( status ) )
		return( status );

	/* Add the DN component to the DN.  If we hit a non-memory related error
	   we turn it into a generic CRYPT_ERROR_BADDATA error since the other
	   codes are somewhat too specific for this case, something like 
	   CRYPT_ERROR_INITED or an arg error isn't too useful for the caller */
	status = insertDNstring( dnComponentListPtrPtr, type, stringBuffer, 
							 valueLength, valueStringType, flags, &dummy );
	return( ( cryptStatusError( status ) && status != CRYPT_ERROR_MEMORY ) ? \
			CRYPT_ERROR_BADDATA : status );
	}