1 /* 2 * Copyright (c) 2017-2020, [Ribose Inc](https://www.ribose.com). 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef STREAM_COMMON_H_ 28 #define STREAM_COMMON_H_ 29 30 #include <stdint.h> 31 #include <stdbool.h> 32 #include <sys/types.h> 33 #include "types.h" 34 35 #define PGP_INPUT_CACHE_SIZE 32768 36 #define PGP_OUTPUT_CACHE_SIZE 32768 37 38 #define PGP_PARTIAL_PKT_FIRST_PART_MIN_SIZE 512 39 40 typedef enum { 41 PGP_STREAM_NULL, 42 PGP_STREAM_FILE, 43 PGP_STREAM_MEMORY, 44 PGP_STREAM_STDIN, 45 PGP_STREAM_STDOUT, 46 PGP_STREAM_PACKET, 47 PGP_STREAM_PARLEN_PACKET, 48 PGP_STREAM_LITERAL, 49 PGP_STREAM_COMPRESSED, 50 PGP_STREAM_ENCRYPTED, 51 PGP_STREAM_SIGNED, 52 PGP_STREAM_ARMORED, 53 PGP_STREAM_CLEARTEXT 54 } pgp_stream_type_t; 55 56 typedef struct pgp_source_t pgp_source_t; 57 typedef struct pgp_dest_t pgp_dest_t; 58 59 typedef bool pgp_source_read_func_t(pgp_source_t *src, void *buf, size_t len, size_t *read); 60 typedef rnp_result_t pgp_source_finish_func_t(pgp_source_t *src); 61 typedef void pgp_source_close_func_t(pgp_source_t *src); 62 63 typedef rnp_result_t pgp_dest_write_func_t(pgp_dest_t *dst, const void *buf, size_t len); 64 typedef rnp_result_t pgp_dest_finish_func_t(pgp_dest_t *src); 65 typedef void pgp_dest_close_func_t(pgp_dest_t *dst, bool discard); 66 67 /* statically preallocated cache for sources */ 68 typedef struct pgp_source_cache_t { 69 uint8_t buf[PGP_INPUT_CACHE_SIZE]; 70 unsigned pos; /* current position in cache */ 71 unsigned len; /* number of bytes available in cache */ 72 bool readahead; /* whether read-ahead with larger chunks allowed */ 73 } pgp_source_cache_t; 74 75 typedef struct pgp_source_t { 76 pgp_source_read_func_t * read; 77 pgp_source_finish_func_t *finish; 78 pgp_source_close_func_t * close; 79 pgp_stream_type_t type; 80 81 uint64_t size; /* size of the data if available, see knownsize */ 82 uint64_t readb; /* number of bytes read from the stream via src_read. Do not confuse with 83 number of bytes as returned via the read since data may be cached */ 84 pgp_source_cache_t *cache; /* cache if used */ 85 void * param; /* source-specific additional data */ 86 87 unsigned eof : 1; /* end of data as reported by read and empty cache */ 88 unsigned knownsize : 1; /* whether size of the data is known */ 89 unsigned error : 1; /* there were reading error */ 90 } pgp_source_t; 91 92 /** @brief helper function to allocate memory for source's cache and param 93 * Also fills src and param with zeroes 94 * @param src pointer to the source structure 95 * @param paramsize number of bytes required for src->param 96 * @return true on success or false if memory allocation failed. 97 **/ 98 bool init_src_common(pgp_source_t *src, size_t paramsize); 99 100 /** @brief read up to len bytes from the source 101 * While this function tries to read as much bytes as possible however it may return 102 * less then len bytes. Then src->eof can be checked if it's end of data. 103 * 104 * @param src source structure 105 * @param buf preallocated buffer which can store up to len bytes 106 * @param len number of bytes to read 107 * @param read number of read bytes will be stored here. Cannot be NULL. 108 * @return true on success or false otherwise 109 **/ 110 bool src_read(pgp_source_t *src, void *buf, size_t len, size_t *read); 111 112 /** @brief shortcut to read exactly len bytes from source. See src_read for parameters. 113 * @return true if len bytes were read or false otherwise (i.e. less then len were read or 114 * read error occurred) */ 115 bool src_read_eq(pgp_source_t *src, void *buf, size_t len); 116 117 /** @brief read up to len bytes and keep them in the cache/do not process 118 * Works only for streams with cache 119 * @param src source structure 120 * @param buf preallocated buffer which can store up to len bytes, or NULL if data should be 121 * discarded, just making sure that needed input is available in source 122 * @param len number of bytes to read. Must be less then PGP_INPUT_CACHE_SIZE. 123 * @param read number of bytes read will be stored here. Cannot be NULL. 124 * @return true on success or false otherwise 125 **/ 126 bool src_peek(pgp_source_t *src, void *buf, size_t len, size_t *read); 127 128 /** @brief shortcut to read exactly len bytes and keep them in the cache/do not process 129 * Works only for streams with cache 130 * @return true if len bytes were read or false otherwise (i.e. less then len were read or 131 * read error occurred) */ 132 bool src_peek_eq(pgp_source_t *src, void *buf, size_t len); 133 134 /** @brief skip up to len bytes. 135 * Note: use src_read() if you want to check error condition/get number of bytes 136 *skipped. 137 * @param src source structure 138 * @param len number of bytes to skip 139 **/ 140 void src_skip(pgp_source_t *src, size_t len); 141 142 /** @brief notify source that all reading is done, so final data processing may be started, 143 * i.e. signature reading and verification and so on. Do not misuse with src_close. 144 * @param src allocated and initialized source structure 145 * @return RNP_SUCCESS or error code. If source doesn't have finish handler then also 146 * RNP_SUCCESS is returned 147 */ 148 rnp_result_t src_finish(pgp_source_t *src); 149 150 /** @brief check whether there were reading error on source 151 * @param allocated and initialized source structure 152 * @return true if there were reading error or false otherwise 153 */ 154 bool src_error(const pgp_source_t *src); 155 156 /** @brief check whether there is no more input on source 157 * @param src allocated and initialized source structure 158 * @return true if there is no more input or false otherwise. 159 * On read error false will be returned. 160 */ 161 bool src_eof(pgp_source_t *src); 162 163 /** @brief close the source and deallocate all internal resources if any 164 */ 165 void src_close(pgp_source_t *src); 166 167 /** @brief skip end of line on the source (\r\n or \n, depending on input) 168 * @param src allocated and initialized source 169 * @return true if eol was found and skipped or false otherwise 170 */ 171 bool src_skip_eol(pgp_source_t *src); 172 173 /** @brief peek the line on the source 174 * @param src allocated and initialized source with data 175 * @param buf preallocated buffer to store the result. Result include NULL character and 176 * doesn't include the end of line sequence. 177 * @param len maximum length of data to store in buf, including terminating NULL 178 * @param read on success here will be stored number of bytes in the string, without the NULL 179 * character. 180 * @return true on success 181 * false is returned if there were eof, read error or eol was not found within the 182 * len. Supported eol sequences are \r\n and \n 183 */ 184 bool src_peek_line(pgp_source_t *src, char *buf, size_t len, size_t *read); 185 186 /** @brief init file source 187 * @param src pre-allocated source structure 188 * @param path path to the file 189 * @return RNP_SUCCESS or error code 190 **/ 191 rnp_result_t init_file_src(pgp_source_t *src, const char *path); 192 193 /** @brief init stdin source 194 * @param src pre-allocated source structure 195 * @return RNP_SUCCESS or error code 196 **/ 197 rnp_result_t init_stdin_src(pgp_source_t *src); 198 199 /** @brief init memory source 200 * @param src pre-allocated source structure 201 * @param mem memory to read from 202 * @param len number of bytes in input 203 * @param free free the memory pointer on stream close or not 204 * @return RNP_SUCCESS or error code 205 **/ 206 rnp_result_t init_mem_src(pgp_source_t *src, const void *mem, size_t len, bool free); 207 208 /** @brief init NULL source, which doesn't allow to read anything and always returns an error. 209 * @param src pre-allocated source structure 210 * @return always RNP_SUCCESS 211 **/ 212 rnp_result_t init_null_src(pgp_source_t *src); 213 214 /** @brief init memory source with contents of other source 215 * @param src pre-allocated source structure 216 * @param readsrc opened source with data 217 * @return RNP_SUCCESS or error code 218 **/ 219 rnp_result_t read_mem_src(pgp_source_t *src, pgp_source_t *readsrc); 220 221 /** @brief init memory source with contents of the specified file 222 * @param src pre-allocated source structure 223 * @param filename name of the file 224 * @return RNP_SUCCESS or error code 225 **/ 226 rnp_result_t file_to_mem_src(pgp_source_t *src, const char *filename); 227 228 /** @brief get memory from the memory source 229 * @param src initialized memory source 230 * @return pointer to the memory or NULL if it is not a memory source 231 **/ 232 const void *mem_src_get_memory(pgp_source_t *src); 233 234 typedef struct pgp_dest_t { 235 pgp_dest_write_func_t * write; 236 pgp_dest_finish_func_t *finish; 237 pgp_dest_close_func_t * close; 238 pgp_stream_type_t type; 239 rnp_result_t werr; /* write function may set this to some error code */ 240 241 size_t writeb; /* number of bytes written */ 242 void * param; /* source-specific additional data */ 243 bool no_cache; /* disable write caching */ 244 uint8_t cache[PGP_OUTPUT_CACHE_SIZE]; 245 unsigned clen; /* number of bytes in cache */ 246 bool finished; /* whether dst_finish was called on dest or not */ 247 } pgp_dest_t; 248 249 /** @brief helper function to allocate memory for dest's param. 250 * Initializes dst and param with zeroes as well. 251 * @param dst dest structure 252 * @param paramsize number of bytes required for dst->param 253 * @return true on success, or false if memory allocation failed 254 **/ 255 bool init_dst_common(pgp_dest_t *dst, size_t paramsize); 256 257 /** @brief write buffer to the destination 258 * 259 * @param dst destination structure 260 * @param buf buffer with data 261 * @param len number of bytes to write 262 * @return true on success or false otherwise 263 **/ 264 void dst_write(pgp_dest_t *dst, const void *buf, size_t len); 265 266 /** @brief printf formatted string to the destination 267 * 268 * @param dst destination structure 269 * @param format format string, which is the same as printf() uses 270 * @param ... additional arguments 271 */ 272 void dst_printf(pgp_dest_t *dst, const char *format, ...); 273 274 /** @brief do all finalization tasks after all writing is done, i.e. calculate and write 275 * mdc, signatures and so on. Do not misuse with dst_close. If was not called then will be 276 * called from the dst_close 277 * 278 * @param dst destination structure 279 * @return RNP_SUCCESS or error code if something went wrong 280 **/ 281 rnp_result_t dst_finish(pgp_dest_t *dst); 282 283 /** @brief close the destination 284 * 285 * @param dst destination structure to be closed 286 * @param discard if this is true then all produced output should be discarded 287 * @return void 288 **/ 289 void dst_close(pgp_dest_t *dst, bool discard); 290 291 /** @brief flush cached data if any. dst_write caches small writes, so data does not 292 * immediately go to stream write function. 293 * 294 * @param dst destination structure 295 * @return void 296 **/ 297 void dst_flush(pgp_dest_t *dst); 298 299 /** @brief init file destination 300 * @param dst pre-allocated dest structure 301 * @param path path to the file 302 * @param overwrite overwrite existing file 303 * @return RNP_SUCCESS or error code 304 **/ 305 rnp_result_t init_file_dest(pgp_dest_t *dst, const char *path, bool overwrite); 306 307 /** @brief init file destination, using the temporary file name, based on path. 308 * Once writing is over, dst_finish() will attempt to rename to the desired name. 309 * @param dst pre-allocated dest structure 310 * @param path path to the file 311 * @param overwrite overwrite existing file on rename 312 * @return RNP_SUCCESS or error code 313 **/ 314 rnp_result_t init_tmpfile_dest(pgp_dest_t *dst, const char *path, bool overwrite); 315 316 /** @brief init stdout destination 317 * @param dst pre-allocated dest structure 318 * @return RNP_SUCCESS or error code 319 **/ 320 rnp_result_t init_stdout_dest(pgp_dest_t *dst); 321 322 /** @brief init memory destination 323 * @param dst pre-allocated dest structure 324 * @param mem pointer to the pre-allocated memory buffer, or NULL if it should be allocated 325 * @param len number of bytes which mem can keep, or maximum amount of memory to allocate if 326 * mem is NULL. If len is zero in later case then allocation is not limited. 327 * @return RNP_SUCCESS or error code 328 **/ 329 rnp_result_t init_mem_dest(pgp_dest_t *dst, void *mem, unsigned len); 330 331 /** @brief set whether to silently discard bytes which overflow memory of the dst. 332 * @param dst pre-allocated and initialized memory dest 333 * @param discard true to discard or false to return an error on overflow. 334 **/ 335 void mem_dest_discard_overflow(pgp_dest_t *dst, bool discard); 336 337 /** @brief get the pointer to the memory where data is written. 338 * Do not retain the result, it may change between calls due to realloc 339 * @param dst pre-allocated and initialized memory dest 340 * @return pointer to the memory area or NULL if memory was not allocated 341 **/ 342 void *mem_dest_get_memory(pgp_dest_t *dst); 343 344 /** @brief get ownership on the memory dest's contents. This must be called only before 345 * closing the dest 346 * @param dst pre-allocated and initialized memory dest 347 * @return pointer to the memory area or NULL if memory was not allocated (i.e. nothing was 348 * written to the destination). Also NULL will be returned on possible (re-)allocation 349 * failure, this case can be identified by non-zero dst->writeb. 350 **/ 351 void *mem_dest_own_memory(pgp_dest_t *dst); 352 353 /** @brief init null destination which silently discards all the output 354 * @param dst pre-allocated dest structure 355 * @return RNP_SUCCESS or error code 356 **/ 357 rnp_result_t init_null_dest(pgp_dest_t *dst); 358 359 /** @brief reads from source and writes to destination 360 * @param src initialized source 361 * @param dst initialized destination 362 * @param limit sets the maximum amount of bytes to be read, 363 * returning an error if the source hasn't come to eof after that amount 364 * if 0, no limit is imposed 365 * @return RNP_SUCCESS or error code 366 **/ 367 rnp_result_t dst_write_src(pgp_source_t *src, pgp_dest_t *dst, uint64_t limit = 0); 368 369 #endif 370