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