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

📄 str_file.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:

	/* If we're doing a read, fetch the data into memory */
	if( mode & FILE_READ )
		{
		FILE *filePtr;
		fldata_t fileData;
		char fileBuffer[ MAX_PATH_LENGTH ];
		int count;

		/* Open the file and determine how large it is */
		filePtr = fopen( fileName, "rb" );
		if( filePtr == NULL )
			return( CRYPT_ERROR_OPEN );
		status = fldata( filePtr, fileBuffer, &fileData );
		if( status )
			{
			fclose( filePtr );
			return( CRYPT_ERROR_OPEN );
			}
		length = fileData.__maxreclen;

		/* Fetch the data into a buffer large enough to contain the entire
		   stream */
		if( ( stream->buffer = clAlloc( "sFileOpen", length ) ) == NULL )
			return( CRYPT_ERROR_MEMORY );
		stream->bufSize = stream->bufEnd = length;
		status = fread( stream->buffer, length, 1, filePtr );
		fclose( filePtr );
		return( ( status != 1 ) ? CRYPT_ERROR_READ : CRYPT_OK );
		}

	/* Allocate the initial I/O buffer for the data */
	if( ( stream->buffer = clAlloc( "sFileOpen", STREAM_BUFSIZE ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	stream->bufSize = STREAM_BUFSIZE;

	return( CRYPT_OK );
#else
	#error Need to add mechanism to connect stream to backing store
	return( CRYPT_ERROR_OPEN );
#endif /* Nonstandard I/O enviroments */
	}

int sFileClose( STREAM *stream )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( stream->type != STREAM_TYPE_NULL );

#if defined( __IBM4758__ )
	/* Close the file and clear the stream structure */
	zeroise( stream->buffer, stream->bufSize );
	clFree( "sFileClose", stream->buffer );
	zeroise( stream, sizeof( STREAM ) );

	return( CRYPT_OK );
#elif defined( __VMCMS__ )
	/* Close the file and clear the stream structure */
	zeroise( stream->buffer, stream->bufSize );
	clFree( "sFileClose", stream->buffer );
	zeroise( stream, sizeof( STREAM ) );

	return( CRYPT_OK );
#else
	#error Need to add mechanism to disconnect stream from backing store
	zeroise( stream, sizeof( STREAM ) );

	return( CRYPT_OK );
#endif /* Nonstandard I/O enviroments */
	}

/* Read/write a block of data from/to a file stream */

int fileRead( STREAM *stream, void *buffer, const int length )
	{
#if defined( __IBM4758__ ) || defined( __VMCMS__ )
	/* These environments move all data into an in-memory buffer when the 
	   file is opened, so there's never any need to read more data from the
	   stream */
	return( CRYPT_ERROR_READ );
#else
	#error Need to add mechanism to read data from backing store
	return( CRYPT_ERROR_READ );
#endif /* Nonstandard I/O enviroments */
	}

int fileWrite( STREAM *stream, const void *buffer, const int length )
	{
#if defined( __IBM4758__ ) || defined( __VMCMS__ )
	/* Expand the write buffer on demand when it fills up.  If it's a small 
	   buffer allocated when we initially read a file and it doesn't look 
	   like we'll be overflowing a standard-size buffer, we first expand it 
	   up to STREAM_BUFSIZE before increasing it in STREAM_BUFSIZE steps.  
	   The following routine does a safe realloc() that wipes the original 
	   buffer */
	void *newBuffer;
	const int newSize = ( stream->bufSize < STREAM_BUFSIZE && \
						  stream->bufPos + length < STREAM_BUFSIZE - 1024 ) ? \
						STREAM_BUFSIZE : stream->bufSize + STREAM_BUFSIZE;

	/* Allocate the buffer and copy the new data across.  If the malloc
	   fails we return CRYPT_ERROR_OVERFLOW rather than CRYPT_ERROR_MEMORY
	   since the former is more appropriate for the emulated-I/O environment */
	if( ( newBuffer = clDynAlloc( "expandBuffer", \
								  stream->bufSize + STREAM_BUFSIZE ) ) == NULL )
		return( CRYPT_ERROR_OVERFLOW );
	memcpy( newBuffer, stream->buffer, stream->bufSize );
	zeroise( stream->buffer, stream->bufSize );
	clFree( "expandBuffer", stream->buffer );
	stream->buffer = newBuffer;
	stream->bufSize = newSize;

	return( CRYPT_OK );
#else
	#error Need to add mechanism to write data to backing store
	return( CRYPT_ERROR_WRITE );
#endif /* Nonstandard I/O enviroments */
	}

/* Commit data in a file stream to backing storage */

int fileFlush( STREAM *stream )
	{
#if defined( __IBM4758__ )
	/* Write the data to flash or BB memory as appropriate */
	if( sccSavePPD( stream->name, stream->buffer, stream->bufEnd,
			( stream->isSensitive ? PPD_BBRAM : PPD_FLASH ) | PPD_TRIPLE ) != PPDGood )
		return( CRYPT_ERROR_WRITE );
	return( CRYPT_OK );
#elif defined( __VMCMS__ )
	/* Under CMS, MVS, TSO, etc the only consistent way to handle writes is
	   to write a fixed-length single-record file containing all the data in
	   one record, so we can't really do anything until the data is flushed */
	FILE *filePtr;
	char formatBuffer[ 64 ];
	int count;

	sprintf( formatBuffer, "wb, recfm=F, lrecl=%d, noseek", stream->bufPos );
	filePtr = fopen( stream->name, formatBuffer );
	if( filePtr == NULL )
		return( CRYPT_ERROR_WRITE );
	count = fwrite( stream->buffer, stream->bufEnd, 1, filePtr );
	fclose( filePtr );
	return( ( count != 1 ) ? CRYPT_ERROR_WRITE : CRYPT_OK );
#else
	#error Need to add mechanism to commit data to backing store
	return( CRYPT_ERROR_WRITE );
#endif /* Nonstandard I/O enviroments */
	}

/* Change the read/write position in a file */

int fileSeek( STREAM *stream, const long position )
	{
#if defined( __IBM4758__ ) || defined( __VMCMS__ )
	/* These environments move all data into an in-memory buffer when the 
	   file is opened, so there's never any need to move around in the
	   stream */
	return( CRYPT_ERROR_READ );
#else
	#error Need to add mechanism to perform virtual seek on backing store
	return( CRYPT_ERROR_READ );
#endif /* Nonstandard I/O enviroments */
	}

/* Check whether a file is writeable */

BOOLEAN fileReadonly( const char *fileName )
	{
	/* Since there's no filesystem, there's no concept of a read-only
	   file - all data items are always accessible */
	return( FALSE );
	}

/* File deletion functions: Wipe a file from the current position to EOF,
   and wipe and delete a file (although it's not terribly rigorous).
   Vestigia nulla retrorsum */

void fileClearToEOF( const STREAM *stream )
	{
#if defined( __IBM4758__ ) || defined( __VMCMS__ )
	/* Data updates on these systems are atomic so there's no remaining data
	   left to clear */
	UNUSED( stream );
#else
  #error Need to add file clear-to-EOF function
#endif /* Nonstandard I/O enviroments */
	}

void fileErase( const char *fileName )
	{
#if defined( __IBM4758__ )
	sccDeletePPD( ( char * ) fileName );
#elif defined( __VMCMS__ )
	FILE *filePtr;
	int length = CRYPT_ERROR, status;

	assert( fileName != NULL );

	/* Determine how large the file is */
	filePtr = fopen( fileName, "rb+" );
	if( filePtr != NULL )
		{
		fldata_t fileData;
		char fileBuffer[ MAX_PATH_LENGTH ];
		int status;

		status = fldata( filePtr, fileBuffer, &fileData );
		if( status == 0 )
			length = fileData.__maxreclen;
		}

	/* If we got a length, overwrite the data.  Since the file contains a
	   single record we can't perform the write-until-done overwrite used 
	   on other OS'es, however since we're only going to be deleting short
	   private key files using the default stream buffer is OK for this */
	if( length > 0 )
		{
		RESOURCE_DATA msgData;
		BYTE buffer[ STREAM_BUFSIZE ];

		length = max( length, STREAM_BUFSIZE );
		setMessageData( &msgData, buffer, length );
		krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
						 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
		fwrite( buffer, 1, length, filePtr );
		}
	if( filePtr != NULL )
		{
		fflush( filePtr );
		fclose( filePtr );
		}
	remove( fileName );
#else
  #error Need to add file erase function
#endif /* Nonstandard I/O enviroments */
	}

/* Build the path to a file in the cryptlib directory */

void fileBuildCryptlibPath( char *path, const char *fileName,
							const BOOLEAN createPath )
	{
	/* Make sure that the open fails if we can't build the path */
	*path = '\0';

	/* Build the path to the configuration file if necessary */
#if defined( __IBM4758__ )
	strcpy( path, fileName );
#elif defined( __VMCMS__ )
	strcpy( path, fileName );
	strcat( path, " p15" );
#else
  #error Need to add function to build the config file path
#endif /* OS-specific file path creation */
	}

/****************************************************************************
*																			*
*								Everything Else								*
*																			*
****************************************************************************/

#else

/* BC++ 3.1 is rather anal-retentive about not allowing extensions when in
   ANSI mode */

#if defined( __STDC__ ) && ( __BORLANDC__ == 0x410 )
  #define fileno( filePtr )		( ( filePtr )->fd )
#endif /* BC++ 3.1 in ANSI mode */

/* When checking whether a file is read-only we also have to check (via 
   errno) to make sure that the file actually exists since the access check 
   will return a false positive for a nonexistant file */

#if defined( __MSDOS16__ ) || defined( __OS2__ ) || defined( __WIN16__ )
  #include <errno.h>
#endif /* __MSDOS16__ || __OS2__ || __WIN16__ */

/* Some OS'es don't define W_OK for the access check */

#ifndef W_OK
  #define W_OK				2
#endif /* W_OK */

/* Symbolic defines for the stdio file access modes */

#define MODE_READ			"rb"
#define MODE_WRITE			"wb"
#define MODE_READWRITE		"rb+"

/* Open/close a file stream */

int sFileOpen( STREAM *stream, const char *fileName, const int mode )
	{
	static const char *modes[] = { MODE_READ, MODE_READ,
								   MODE_WRITE, MODE_READWRITE };
	const char *openMode;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( fileName != NULL );
	assert( mode != 0 );

	/* Initialise the stream structure */
	memset( stream, 0, sizeof( STREAM ) );
	stream->type = STREAM_TYPE_FILE;
	if( ( mode & FILE_RW_MASK ) == FILE_READ )
		stream->flags = STREAM_FLAG_READONLY;
	openMode = modes[ mode & FILE_RW_MASK ];

	/* If we're trying to write to the file, check whether we've got
	   permission to do so */
	if( ( mode & FILE_WRITE ) && fileReadonly( fileName ) )
		return( CRYPT_ERROR_PERMISSION );

#if defined( __MSDOS16__ ) || defined( __WIN16__ ) || defined( __OS2__ ) || \
	defined( __SYMBIAN32__ ) 
	/* Try and open the file */
	stream->filePtr = fopen( fileName, openMode );
	if( stream->filePtr == NULL )
		/* The open failed, determine whether it was because the file doesn't
		   exist or because we can't use that access mode */
		return( ( access( fileName, 0 ) == -1 ) ? CRYPT_ERROR_NOTFOUND : \
												  CRYPT_ERROR_OPEN );
#elif defined( __TANDEMNSK__ )
	stream->filePtr = fopen( fileName, openMode );
	if( stream->filePtr == NULL )
		return( ( errno == ENOENT ) ? \
				CRYPT_ERROR_NOTFOUND : CRYPT_ERROR_OPEN );
#else
  #error Need to add file accessibility call
#endif /* OS-specific file accessibility check */

	return( CRYPT_OK );
	}

int sFileClose( STREAM *stream )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( stream->type == STREAM_TYPE_FILE );

	/* Close the file and clear the stream structure */
	fclose( stream->filePtr );
	zeroise( stream, sizeof( STREAM ) );

	return( CRYPT_OK );
	}

/* Read/write a block of data from/to a file stream */

int fileRead( STREAM *stream, void *buffer, const int length )
	{
	int bytesRead;

	if( ( bytesRead = fread( buffer, 1, length, stream->filePtr ) ) < length && \
		( bytesRead < 0 || ferror( stream->filePtr ) ) )
		return( CRYPT_ERROR_READ );
	return( bytesRead );
	}

int fileWrite( STREAM *stream, const void *buffer, const int length )
	{
	if( fwrite( buffer, 1, length, stream->filePtr ) != length )
		return( CRYPT_ERROR_WRITE );
	return( CRYPT_OK );
	}

/* Commit data in a file stream to backing storage */

int fileFlush( STREAM *stream )
	{
	fflush( stream->filePtr );
	return( CRYPT_OK );
	}

/* Change the read/write position in a file */

int fileSee

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -