1 /****************************************************************************
2 *																			*
3 *					STREAM Class Constants and Structures					*
4 *					  Copyright Peter Gutmann 1993-2007						*
5 *																			*
6 ****************************************************************************/
7 
8 #ifndef _STREAM_DEFINED
9 
10 #define _STREAM_DEFINED
11 
12 #if defined( INC_ALL )
13   #include "crypt.h"
14 #else
15   #include "crypt.h"
16 #endif /* Compiler-specific includes */
17 #if defined( __WIN32__ ) || defined( __WINCE__ )
18   /* Includes are always handled via the normal system includes */
19 #elif defined( __UNIX__ ) || defined( __BEOS__ ) || defined( __XMK__ )
20   #include <unistd.h>		/* For lseek() codes */
21 #elif defined( __MAC__ )
22   #include <Files.h>
23 #elif defined( __Nucleus__ )
24   #include <nucleus.h>
25   #include <pcdisk.h>
26 #elif defined( __PALMOS__ )
27   #include <VFSMgr.h>
28 #elif defined( __SMX__ )
29   #include <smx.h>
30   #include <smxfs.h>
31 #elif defined( __UCOSII__ )
32   #include <fs_api.h>	/* For uC/FS 2.x, renamed to fs.h in 3.x */
33 #elif !defined( CONFIG_NO_STDIO )
34   #include <stdio.h>
35 #endif /* System-specific file I/O headers */
36 
37 /****************************************************************************
38 *																			*
39 *								Stream Constants							*
40 *																			*
41 ****************************************************************************/
42 
43 /* Access/option flags for the file stream open call.  These are:
44 
45 	FLAG_EXCLUSIVE_ACCESS: Lock the file so that other threads/processes
46 		can't open it until the current thread/process closes it.  This flag
47 		is implicitly set if the file R/W bits (via FLAG_RW_MASK) are
48 		FILE_WRITE, which creates a new file.
49 
50 	FLAG_READ/FLAG_WRITE: Open file for read/write access.
51 
52 	FLAG_PRIVATE/FLAG_SENSITIVE: Specify the sensitivity of data in a file.
53 		The difference between the private and sensitive flags is that some
54 		data may be private for a given user but not sensitive (e.g.config
55 		info) while other data may be private and sensitive (e.g.private
56 		keys).  The sensitive flag only has an effect on special systems
57 		where data can be committed to secure storage, since there's usually
58 		a very limited amount of this available we only use it for sensitive
59 		data but not generic private data */
60 
61 #define FILE_FLAG_NONE		0x00	/* No file flag */
62 #define FILE_FLAG_READ		0x01	/* Open file for read access */
63 #define FILE_FLAG_WRITE		0x02	/* Open file for write access */
64 #define FILE_FLAG_EXCLUSIVE_ACCESS 0x04	/* Don't allow others access */
65 #define FILE_FLAG_PRIVATE	0x08	/* Set ACL's to allow owner access only */
66 #define FILE_FLAG_SENSITIVE	0x10	/* Use secure storage if available */
67 #define FILE_FLAG_RW_MASK	0x03	/* Mask for R/W bits */
68 #define FILE_FLAG_MAX		0x1F	/* Maximum possible flag value */
69 
70 /* Options for the build-path call */
71 
72 typedef enum {
73 	BUILDPATH_NONE,					/* No option type */
74 	BUILDPATH_CREATEPATH,			/* Get path to config file, create if nec.*/
75 	BUILDPATH_GETPATH,				/* Get path to config file */
76 	BUILDPATH_RNDSEEDFILE,			/* Get path to random seed file */
77 	BUILDPATH_LAST					/* Last valid option type */
78 	} BUILDPATH_OPTION_TYPE;
79 
80 /* Stream IOCTL types.  These are:
81 
82 	IOCTL_CLOSESENDCHANNEL: Network streams, perform a sender-side close of
83 		the network channel.
84 
85 	IOCTL_CONNSTATE/IOCTL_LASTMESSAGE: Network streams, manage the last
86 		message in a stream.  IOCTL_LASTMESSAGE is write-only and specifies
87 		that this is the last message to be sent, handled in HTTP by adding
88 		a "Connection: close" to the header.  IOCTL_CONNSTATE is read-only
89 		and specifies that the peer has indicated that this is the last
90 		message to be received (typically by the recipient seeing an HTTP
91 		"Connection: close"), so that after processing this message the
92 		channel is considered closed.
93 
94 	IOCTL_ERRORINFO: Set extended error information for the stream.
95 
96 	IOCTL_GETxxx: Network stream, get various network-related parameters.
97 
98 	IOCTL_HANDSHAKECOMPLETE: Network streams, change the stream timeout
99 		value from being applied to the handshake phase to being applied to
100 		the data read/write phase.  Typically the handshake is blocking
101 		while the data read/write is nonblocking, so different timeouts
102 		apply.
103 
104 	IOCTL_HTTPREQTYPES: Network streams, specify the HTTP request types (as
105 		a STREAM_HTTPREQTYPE_xxx) that are permitted for this stream.
106 
107 	IOCTL_IOBUFFER: File streams, set/clear the working buffer for I/O.
108 
109 	IOCTL_PARTIALREAD/IOCTL_PARTIALWRITE: File streams, allow a read or
110 		write of less than the total data amount specified in the length
111 		parameter, used when working with virtual file streams that have
112 		been translated into memory streams by the stream.c buffering.
113 
114 	IOCTL_READTIMEOUT/IOCTL_WRITETIMEOUT: Network streams, set the read/
115 		write timeout */
116 
117 typedef enum {
118 	STREAM_IOCTL_NONE,				/* No IOCTL type */
119 	STREAM_IOCTL_IOBUFFER,			/* Working buffer for file streams */
120 	STREAM_IOCTL_PARTIALREAD,		/* Allow read of less than req.amount */
121 	STREAM_IOCTL_PARTIALWRITE,		/* Allow write of less then req.amount */
122 	STREAM_IOCTL_READTIMEOUT,		/* Network read timeout */
123 	STREAM_IOCTL_WRITETIMEOUT,		/* Network write timeout */
124 	STREAM_IOCTL_HANDSHAKECOMPLETE,	/* Toggle handshake vs.data timeout */
125 	STREAM_IOCTL_CONNSTATE,			/* Connection state (open/closed) */
126 	STREAM_IOCTL_LASTMESSAGE,		/* Last message in transaction */
127 	STREAM_IOCTL_GETCLIENTNAME,		/* Get client name */
128 	STREAM_IOCTL_GETCLIENTNAMELEN,	/* Get client name length */
129 	STREAM_IOCTL_GETCLIENTPORT,		/* Get client port */
130 	STREAM_IOCTL_GETPEERTYPE,		/* Get peer system type */
131 	STREAM_IOCTL_HTTPREQTYPES,		/* Permitted HTTP request types */
132 	STREAM_IOCTL_CLOSESENDCHANNEL,	/* Close send side of channel */
133 	STREAM_IOCTL_ERRORINFO,			/* Set stream extended error info */
134 	STREAM_IOCTL_LAST				/* Last possible IOCTL type */
135 	} STREAM_IOCTL_TYPE;
136 
137 /* Options for STREAM_IOCTL_HTTPREQTYPES */
138 
139 typedef enum {
140 	STREAM_HTTPREQTYPE_NONE,		/* No HTTP request type */
141 	STREAM_HTTPREQTYPE_GET,			/* HTTP GET only */
142 	STREAM_HTTPREQTYPE_POST,		/* HTTP POST only */
143 	STREAM_HTTPREQTYPE_POST_AS_GET,	/* HTTP GET acting as a POST (b0rken svrs) */
144 	STREAM_HTTPREQTYPE_ANY,			/* HTTP GET or POST */
145 	STREAM_HTTPREQTYPE_LAST			/* Last possible HTTP request type */
146 	} STREAM_HTTPREQTYPE_TYPE;
147 
148 /* Options for STREAM_IOCTL_GETPEERTYPE */
149 
150 typedef enum {
151 	STREAM_PEER_NONE,					/* No information available */
152 	STREAM_PEER_MICROSOFT,				/* Microsoft IIS */
153 	STREAM_PEER_LAST
154 	} STREAM_PEER_TYPE;
155 
156 /* Stream network protocol types */
157 
158 typedef enum {
159 	STREAM_PROTOCOL_NONE,			/* No protocol type */
160 	STREAM_PROTOCOL_TCP,			/* TCP */
161 	STREAM_PROTOCOL_UDP,			/* UDP */
162 	STREAM_PROTOCOL_HTTP,			/* HTTP */
163 	STREAM_PROTOCOL_LAST			/* Last possible protocol type */
164 	} STREAM_PROTOCOL_TYPE;
165 
166 /* The size of the I/O buffer used to read/write data from/to streams backed
167    by persistent files.  These are allocated on-demand on the stack, so they
168    shouldn't be made too big.  In addition since they may correspond
169    directly to underlying storage media blocks (e.g. disk sectors or flash
170    memory segments) they shouldn't be made smaller than the underlying
171    blocksize either.  Finally, they should be a power of two (this isn't a
172    strict requirement of the code, but is in a good idea in general because
173    of storage media constraints) */
174 
175 #ifdef CONFIG_CONSERVE_MEMORY
176   #define STREAM_BUFSIZE		512
177 #else
178   #define STREAM_BUFSIZE		4096
179 #endif /* CONFIG_CONSERVE_MEMORY */
180 
181 /****************************************************************************
182 *																			*
183 *								Stream Structures							*
184 *																			*
185 ****************************************************************************/
186 
187 /* The STREAM data type */
188 
189 typedef struct ST {
190 	/* General information for the stream */
191 	int type;					/* The stream type, of type STREAM_TYPE */
192 	int flags;					/* Stream flags */
193 	int status;					/* Current stream status (clib error code) */
194 
195 	/* Information for memory I/O */
196 	BUFFER_OPT( bufSize, bufEnd ) \
197 	BYTE *buffer;				/* Buffer to R/W to */
198 	int bufSize;				/* Total size of buffer */
199 	int bufPos;					/* Current position in buffer */
200 	int bufEnd;					/* Last buffer position with valid data */
201 
202 	/* Information for file I/O */
203 	int bufCount;				/* File position quantised by buffer size */
204 #if defined( __WIN32__ ) || defined( __WINCE__ )
205 	HANDLE hFile;				/* Backing file for the stream */
206   #ifdef __TESTIO__
207 	char name[ MAX_PATH_LENGTH + 8 ];/* Data item associated with stream */
208   #endif /* __TESTIO__ */
209 #elif defined( __AMX__ ) || defined( __Android__ ) || \
210 	  defined( __BEOS__ ) || defined( __ECOS__ ) || defined( __iOS__ ) || \
211 	  ( defined( __MVS__ ) && !defined( CONFIG_NO_STDIO ) ) || \
212 	  defined( __RTEMS__ ) || defined( __SYMBIAN32__ ) || \
213 	  defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ ) || \
214 	  defined( __UNIX__ ) || defined( __VxWorks__ ) || defined( __XMK__ )
215 	int fd;						/* Backing file for the stream */
216   #ifdef __TESTIO__
217 	char name[ MAX_PATH_LENGTH + 8 ];/* Data item associated with stream */
218   #endif /* __TESTIO__ */
219 #elif defined( __MAC__ )
220 	short refNum;				/* File stream reference number */
221 	FSSpec fsspec;				/* File system specification */
222 #elif defined( __PALMOS__ )
223 	FileRef fileRef;			/* File reference number */
224 #elif defined( __SMX__ )
225 	FILEHANDLE filePtr;			/* File associated with this stream */
226 #elif defined( __FileX__ )
227 	FX_FILE filePtr;			/* File associated with this stream */
228 	long position;				/* Position in file */
229 #elif defined( __UCOSII__ )
230 	FS_FILE *pFile;				/* File associated with this stream */
231 #elif defined( CONFIG_NO_STDIO )
232   #if defined( __IBM4758__ )
233 	char name[ 8 + 1 ];			/* Data item associated with stream */
234 	BOOLEAN isSensitive;		/* Whether stream contains sensitive data */
235   #elif defined( __MVS__ ) || defined( __VMCMS__ ) || defined( __TESTIO__ )
236 	char name[ MAX_PATH_LENGTH + 8 ];/* Data item associated with stream */
237   #endif /* Nonstandard I/O enviroments */
238 #elif defined( __Nucleus__ )
239 	INT fd;						/* File handle */
240 #else
241 	FILE *filePtr;				/* The file associated with this stream */
242 #endif /* System-specific file I/O information */
243 
244 	/* Network stream information.  This is dynamically allocated since it's
245 	   only used for (relatively rare) network streams and would lead to a
246 	   lot of wasted memory in the memory streams that are used constantly
247 	   throughout cryptlib */
248 #ifdef USE_TCP
249 	void *netStreamInfo;
250 #endif /* USE_TCP */
251 	} STREAM;
252 
253 /* Parsed URL information: schema://user@host:port/location.  This is used
254    to parse URL data from an in-memory string and encodes pointers to
255    locations in the string data */
256 
257 typedef enum { URL_TYPE_NONE, URL_TYPE_HTTP, URL_TYPE_HTTPS, URL_TYPE_SSH,
258 			   URL_TYPE_CMP, URL_TYPE_TSP, URL_TYPE_LDAP,
259 			   URL_TYPE_LAST } URL_TYPE;
260 
261 typedef struct {
262 	URL_TYPE type;
263 	BUFFER_OPT_FIXED( schemaLen ) \
264 	const char *schema;
265 	int schemaLen;
266 	BUFFER_OPT_FIXED( userInfoLen ) \
267 	const char *userInfo;
268 	int userInfoLen;
269 	BUFFER_OPT_FIXED( hostLen ) \
270 	const char *host;
271 	int hostLen;
272 	BUFFER_OPT_FIXED( locationLen ) \
273 	const char *location;
274 	int locationLen;
275 	int port;
276 	} URL_INFO;
277 
278 /* Parsed HTTP URI information: location?attribute=value.  The contents of a
279    string-form URI are broken down into the following fields by the HTTP
280    read code */
281 
282 typedef struct {
283 	BUFFER( CRYPT_MAX_TEXTSIZE, locationLen ) \
284 	char location[ CRYPT_MAX_TEXTSIZE + 8 ];
285 	BUFFER( CRYPT_MAX_TEXTSIZE, attributeLen ) \
286 	char attribute[ CRYPT_MAX_TEXTSIZE + 8 ];
287 	BUFFER( CRYPT_MAX_TEXTSIZE, valueLen ) \
288 	char value[ CRYPT_MAX_TEXTSIZE + 8 ];
289 	BUFFER( CRYPT_MAX_TEXTSIZE, extraDataLen ) \
290 	char extraData[ CRYPT_MAX_TEXTSIZE + 8 ];
291 	int locationLen, attributeLen, valueLen, extraDataLen;
292 	} HTTP_URI_INFO;
293 
294 /* Information required when connecting a network stream.  There are so many
295    parameters required that we pack them into a struct to keep the interface
296    more manageable */
297 
298 typedef enum {
299 	NET_OPTION_NONE,			/* No connect option type */
300 	NET_OPTION_HOSTNAME,		/* Use host/interface name + port */
301 	NET_OPTION_TRANSPORTSESSION,/* Use network transport session */
302 	NET_OPTION_NETWORKSOCKET,	/* Use user-supplied network socket */
303 	NET_OPTION_NETWORKSOCKET_DUMMY,	/* Dummy open to check socket OK */
304 	NET_OPTION_LAST				/* Last possible connect option type */
305 	} NET_OPTION_TYPE;
306 
307 typedef struct {
308 	/* Network link information, either a remote host and port, a pre-
309 	   connected network socket, or a cryptlib transport session */
310 	BUFFER_OPT_FIXED( nameLength ) \
311 	const char *name;
312 	int nameLength;
313 	int port;					/* Remote host info */
314 	const char *interface;
315 	int interfaceLength;		/* Local interface info */
316 	int networkSocket;			/* Pre-connected network socket */
317 	CRYPT_SESSION iCryptSession;/* cryptlib transport session */
318 
319 	/* Auxiliary information: Owning user object, network status
320 	   information, general option type */
321 	CRYPT_USER iUserObject;		/* Owning user object */
322 	int timeout, connectTimeout;/* Connect and data xfer.timeouts */
323 	NET_OPTION_TYPE options;	/* Connect options */
324 	} NET_CONNECT_INFO;
325 
326 #define initNetConnectInfo( netConnectInfo, netUserObject, netTimeout, \
327 							netConnectTimeout, netOption ) \
328 	{ \
329 	memset( netConnectInfo, 0, sizeof( NET_CONNECT_INFO ) ); \
330 	( netConnectInfo )->networkSocket = CRYPT_ERROR; \
331 	( netConnectInfo )->iCryptSession = CRYPT_ERROR; \
332 	( netConnectInfo )->iUserObject = netUserObject; \
333 	( netConnectInfo )->timeout = netTimeout; \
334 	( netConnectInfo )->connectTimeout = netConnectTimeout; \
335 	( netConnectInfo )->options = netOption; \
336 	}
337 
338 /* Information required when reading from/writing to an HTTP stream.
339    Although we're in theory just using HTTP as a universal substrate,
340    there's a pile of additional HTTP-related data that we have to convey,
341    so when we perform a read or write to an HTTP stream we use a composite
342    data parameter */
343 
344 typedef struct {
345 	/* Data payload informtion.  On read the { buffer, bufSize } is the
346 	   amount of buffer space available to read data, with bytesAvail being
347 	   the length of the data item being read into the buffer and
348 	   bytesTransferred being the amount of data actually transferred.  On
349 	   write the { buffer, bufSize } is the data to write and
350 	   bytesTransferred is the amount actually transferred.  We have to
351 	   store this information here because the write call is passed the
352 	   HTTP_DATA_INFO structure rather than the data buffer so we can't
353 	   return a bytes-read or written count as the return value */
354 	BUFFER_UNSPECIFIED( bufSize ) \
355 	void *buffer;					/* Data buffer */
356 	int bufSize;					/* Size of data buffer */
357 	int bytesAvail, bytesTransferred;	/* Actual data bytes on read */
358 	BUFFER_FIXED( contentTypeLen ) \
359 	const char *contentType;		/* HTTP content type */
360 	int contentTypeLen;
361 
362 	/* HTTP read/write control flags.  If the bufferResize flag is set then
363 	   the HTTP read code can dynamically resize the buffer in order to read
364 	   arbitrary-length input.  If the buffer was resized during the read
365 	   then the flag is returned set and the caller has to reset their read
366 	   buffer to { buffer, bufSize }.  If no resize took place then the flag
367 	   is returned cleared.
368 
369 	   If the responseIsText flag is set then a text/plain response from the
370 	   server is valid.  Normally messages have application-specific message
371 	   types and the only time we'd see plain text is if the server is
372 	   returning an error message (usually outside the spec of the protocol
373 	   that we're talking), however if additional capabilities have been
374 	   kludged onto the protocol via text-format messages then a response-
375 	   type of text/pain is valid */
376 	BOOLEAN bufferResize;			/* Buffer is resizeable */
377 	BOOLEAN responseIsText;			/* Response from svr.is text/plain */
378 
379 	/* The client's request type and request info (for HTTP GET), and the
380 	   server's status in response to a client GET request */
381 	STREAM_HTTPREQTYPE_TYPE reqType;/* HTTP request type */
382 	HTTP_URI_INFO *reqInfo;
383 	int reqStatus;				/* HTTP status in response to request */
384 	} HTTP_DATA_INFO;
385 
386 #define initHttpDataInfo( httpDataInfo, dataBuffer, dataLength ) \
387 	{ \
388 	memset( httpDataInfo, 0, sizeof( HTTP_DATA_INFO ) ); \
389 	( httpDataInfo )->buffer= dataBuffer; \
390 	( httpDataInfo )->bufSize = dataLength; \
391 	}
392 #define initHttpDataInfoEx( httpDataInfo, dataBuffer, dataLength, uriInfo ) \
393 	{ \
394 	memset( httpDataInfo, 0, sizeof( HTTP_DATA_INFO ) ); \
395 	( httpDataInfo )->buffer= dataBuffer; \
396 	( httpDataInfo )->bufSize = dataLength; \
397 	( httpDataInfo )->reqInfo = uriInfo; \
398 	}
399 
400 /****************************************************************************
401 *																			*
402 *							Stream Function Prototypes						*
403 *																			*
404 ****************************************************************************/
405 
406 /* Functions corresponding to traditional/stdio-type I/O.
407 
408    The annotation for sread() and swrite() are a bit dishonest in that in
409    almost all cases what's returned is a pure status code, it's only for
410    network streams and special-case streams that allow partial reads that a
411    length can be returned.  If we were to use CHECK_RETVAL_LENGTH then the
412    belief that a returned status value isn't really a true status gets
413    propagated up through every function that reads or writes data, leading
414    to endless false-positive warnings */
415 
416 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
417 int sputc( INOUT STREAM *stream, IN_BYTE const int ch );
418 CHECK_RETVAL_RANGE( 0, 0xFF ) STDC_NONNULL_ARG( ( 1 ) ) \
419 int sgetc( INOUT STREAM *stream );
420 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
421 int sread( INOUT STREAM *stream,
422 		   OUT_BUFFER_FIXED( length ) void *buffer,
423 		   IN_LENGTH const int length );
424 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
425 int swrite( INOUT STREAM *stream,
426 		    IN_BUFFER( length ) const void *buffer,
427 			IN_LENGTH const int length );
428 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
429 int sflush( INOUT STREAM *stream );
430 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
431 int sseek( INOUT STREAM *stream, IN_LENGTH_Z const long position );
432 CHECK_RETVAL_RANGE_NOERROR( 0, MAX_BUFFER_SIZE ) STDC_NONNULL_ARG( ( 1 ) ) \
433 int stell( const STREAM *stream );
434 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
435 int sioctlSet( INOUT STREAM *stream,
436 			   IN_ENUM( STREAM_IOCTL ) const STREAM_IOCTL_TYPE type,
437 			   const int value );
438 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
439 int sioctlSetString( INOUT STREAM *stream,
440 					 IN_ENUM( STREAM_IOCTL ) const STREAM_IOCTL_TYPE type,
441 					 IN_BUFFER( dataLen ) const void *data,
442 					 IN_DATALENGTH const int dataLen );
443 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
444 int sioctlGet( INOUT STREAM *stream,
445 			   IN_ENUM( STREAM_IOCTL ) const STREAM_IOCTL_TYPE type,
446 			   OUT_BUFFER_FIXED( dataMaxLen ) void *data,
447 			   IN_LENGTH_SHORT const int dataMaxLen );
448 
449 /* Nonstandard functions: Skip a number of bytes in a stream, peek at the
450    next value in the stream.  The sSkip() call applies a bounds check, the
451    define SSKIP_MAX can be used to denote the maximum length allowed */
452 
453 #define SSKIP_MAX	( MAX_BUFFER_SIZE - 1 )
454 
455 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
456 int sSkip( INOUT STREAM *stream, const long offset,
457 		   IN_DATALENGTH const long maxOffset );
458 CHECK_RETVAL_RANGE( 0, 0xFF ) STDC_NONNULL_ARG( ( 1 ) ) \
459 int sPeek( INOUT STREAM *stream );
460 
461 /* Inquire as to the health of a stream.  Currently these are only used in
462    debugging assertions, in int_api.c when exporting attributes to a stream,
463    and as a safety check in ssl_rw.c/ssh2_rw.c when wrapping a packet that
464    needs direct access to a memory stream */
465 
466 #define sGetStatus( stream )		( stream )->status
467 #define sStatusOK( stream )			cryptStatusOK( ( stream )->status )
468 
469 /* Set/clear a user-defined error state for the stream */
470 
471 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
472 int sSetError( INOUT STREAM *stream, IN_ERROR const int status );
473 STDC_NONNULL_ARG( ( 1 ) ) \
474 void sClearError( INOUT STREAM *stream );
475 
476 /* Stream query functions to determine whether a stream is a null stream,
477    a memory-mapped file stream, or a virtual file stream.  The null stream
478    check is used to short-circuit unnecessary data transfers in higher-level
479    code where writing to a null stream is used to determine overall data
480    sizes.  The memory-mapped stream check is used when we can eliminate
481    extra buffer allocation if all data is available in memory.  The virtual
482    file stream check is used where the low-level access routines have
483    converted a file on a CONFIG_NO_STDIO system to a memory stream that acts
484    like a file stream */
485 
486 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \
487 BOOLEAN sIsNullStream( const STREAM *stream );
488 
489 /* Functions to work with memory streams.  A null stream is a special case of a
490    memory stream that just acts as a data sink.  In some cases we may want to
491    open either a null stream or a standard memory stream depending on whether
492    the caller has specified an output buffer or not, in this case we provide a
493    function sMemOpenOpt() to indicate that it's OK for the buffer value to be
494    NULL.
495 
496    Note that the open/connect functions are declared with a void return
497    type, this is because they're used in hundreds of locations and the only
498    situation in which they can fail is a programming error.  Because of
499    this, problems are caught by throwing exceptions in debug builds rather
500    than having to add error handling for every case where they're used.  In
501    addition the functions always initialise the stream, setting it to an
502    invalid stream if there's an error, so there's no real need to check a
503    return value */
504 
505 STDC_NONNULL_ARG( ( 1, 2 ) ) \
506 void sMemOpen( OUT STREAM *stream,
507 			   OUT_BUFFER_FIXED( length ) void *buffer,
508 			   IN_LENGTH const int length );
509 STDC_NONNULL_ARG( ( 1 ) ) \
510 void sMemOpenOpt( OUT STREAM *stream,
511 				  OUT_BUFFER_OPT_FIXED( length ) void *buffer,
512 				  IN_LENGTH_Z const int length );
513 STDC_NONNULL_ARG( ( 1 ) ) \
514 void sMemNullOpen( OUT STREAM *stream );
515 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
516 int sMemClose( INOUT STREAM *stream );
517 STDC_NONNULL_ARG( ( 1, 2 ) ) \
518 void sMemConnect( OUT STREAM *stream,
519 				  IN_BUFFER( length ) const void *buffer,
520 				  IN_LENGTH const int length );
521 #ifndef NDEBUG
522 STDC_NONNULL_ARG( ( 1, 2 ) ) \
523 void sMemPseudoConnect( OUT STREAM *stream,
524 					    IN_BUFFER( length ) const void *buffer,
525 					    IN_LENGTH const int length );
526 #endif /* !NDEBUG */
527 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
528 int sMemDisconnect( INOUT STREAM *stream );
529 
530 /* Memory stream direct-access functions, used when the contents of a memory
531    stream need to be encrypted/decrypted/signed/MACd.  The basic
532    sMemGetDataBlock() returns a data block of a given size from the current
533    stream position, sMemGetDataBlockAbs() returns a data block from the
534    given stream position, and sMemGetDataBlockRemaining() returns a data
535    block containing all remaining data available in the stream.  The stream
536    parameter is given as an INOUT even though the stream contents aren't
537    strictly affected because the functions can set the stream error state
538    in the case of a failure */
539 
540 CHECK_RETVAL_RANGE_NOERROR( 0, MAX_BUFFER_SIZE ) STDC_NONNULL_ARG( ( 1 ) ) \
541 int sMemDataLeft( const STREAM *stream );
542 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
543 int sMemGetDataBlock( INOUT STREAM *stream,
544 					  OUT_BUFFER_ALLOC_OPT( dataSize ) void **dataPtrPtr,
545 					  IN_DATALENGTH const int dataSize );
546 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
547 int sMemGetDataBlockAbs( INOUT STREAM *stream,
548 						 IN_DATALENGTH_Z const int position,
549 						 OUT_BUFFER_ALLOC_OPT( dataSize ) void **dataPtrPtr,
550 						 IN_DATALENGTH const int dataSize );
551 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
552 int sMemGetDataBlockRemaining( INOUT STREAM *stream,
553 							   OUT_BUFFER_ALLOC_OPT( *length ) void **dataPtrPtr,
554 							   OUT_DATALENGTH_Z int *length );
555 
556 /* Functions to work with file streams */
557 
558 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
559 int sFileOpen( OUT STREAM *stream, IN_STRING const char *fileName,
560 			   IN_FLAGS( FILE ) const int mode );
561 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
562 int sFileClose( INOUT STREAM *stream );
563 
564 /* Convert a file stream to a memory stream */
565 
566 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
567 int sFileToMemStream( OUT STREAM *memStream,
568 					  INOUT STREAM *fileStream,
569 					  OUT_BUFFER_ALLOC_OPT( length ) void **bufPtrPtr,
570 					  IN_DATALENGTH const int length );
571 
572 /* Special-case file I/O calls */
573 
574 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \
575 BOOLEAN fileReadonly( IN_STRING const char *fileName );
576 STDC_NONNULL_ARG( ( 1 ) ) \
577 void fileClearToEOF( STREAM *stream );
578 STDC_NONNULL_ARG( ( 1 ) ) \
579 void fileErase( IN_STRING const char *fileName );
580 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
581 int fileBuildCryptlibPath( OUT_BUFFER( pathMaxLen, *pathLen ) char *path,
582 						   IN_LENGTH_SHORT const int pathMaxLen,
583 						   OUT_LENGTH_BOUNDED_Z( pathMaxLen ) int *pathLen,
584 						   IN_BUFFER( fileNameLen ) const char *fileName,
585 						   IN_LENGTH_SHORT const int fileNameLen,
586 						   IN_ENUM( BUILDPATH ) \
587 								const BUILDPATH_OPTION_TYPE option );
588 
589 /* Functions to work with network streams */
590 
591 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
592 int sNetParseURL( OUT URL_INFO *urlInfo,
593 				  IN_BUFFER( urlLen ) const BYTE *url,
594 				  IN_LENGTH_SHORT const int urlLen,
595 				  IN_ENUM_OPT( URL_TYPE ) const URL_TYPE urlTypeHint );
596 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
597 int sNetConnect( OUT STREAM *stream,
598 				 IN_ENUM( STREAM_PROTOCOL ) const STREAM_PROTOCOL_TYPE protocol,
599 				 const NET_CONNECT_INFO *connectInfo,
600 				 OUT ERROR_INFO *errorInfo );
601 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
602 int sNetListen( OUT STREAM *stream,
603 				IN_ENUM( STREAM_PROTOCOL ) const STREAM_PROTOCOL_TYPE protocol,
604 				const NET_CONNECT_INFO *connectInfo,
605 				OUT ERROR_INFO *errorInfo );
606 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
607 int sNetDisconnect( INOUT STREAM *stream );
608 STDC_NONNULL_ARG( ( 1, 2 ) ) \
609 void sNetGetErrorInfo( INOUT STREAM *stream, OUT ERROR_INFO *errorInfo );
610 
611 /* Initialisation/shutdown functions for network stream interfaces */
612 
613 #ifdef USE_TCP
614   RETVAL \
615   int netInitTCP( void );
616   void netSignalShutdown( void );
617   void netEndTCP( void );
618 #else
619   #define netInitTCP()						CRYPT_OK
620   #define netSignalShutdown()
621   #define netEndTCP()
622 #endif /* NET_TCP */
623 
624 #endif /* _STREAM_DEFINED */
625