Changeset 320
- Timestamp:
- 12/07/05 09:39:44
- Files:
-
- openpgpsdk/trunk/examples/common.c (modified) (2 diffs)
- openpgpsdk/trunk/examples/packet-dump.c (modified) (4 diffs)
- openpgpsdk/trunk/examples/verify.c (modified) (2 diffs)
- openpgpsdk/trunk/examples/verify2.c (modified) (5 diffs)
- openpgpsdk/trunk/include/openpgpsdk/armour.h (modified) (1 diff)
- openpgpsdk/trunk/include/openpgpsdk/errors.h (modified) (1 diff)
- openpgpsdk/trunk/include/openpgpsdk/packet-parse.h (modified) (2 diffs)
- openpgpsdk/trunk/include/openpgpsdk/util.h (modified) (1 diff)
- openpgpsdk/trunk/src/accumulate.c (modified) (6 diffs)
- openpgpsdk/trunk/src/armour.c (modified) (31 diffs)
- openpgpsdk/trunk/src/compress.c (modified) (5 diffs)
- openpgpsdk/trunk/src/create.c (modified) (2 diffs)
- openpgpsdk/trunk/src/errors.c (modified) (3 diffs)
- openpgpsdk/trunk/src/packet-parse.c (modified) (62 diffs)
- openpgpsdk/trunk/src/util.c (modified) (5 diffs)
- openpgpsdk/trunk/src/validate.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
openpgpsdk/trunk/examples/common.c
r305 r320 5 5 #include <assert.h> 6 6 7 static ops_parse_c allback_return_t8 callback(const ops_parser_content_t *content, void *arg_)7 static ops_parse_cb_return_t 8 callback(const ops_parser_content_t *content,ops_parse_cb_info_t *cbinfo) 9 9 { 10 ops_secret_key_t **skey= arg_;10 ops_secret_key_t **skey=ops_parse_cb_get_arg(cbinfo); 11 11 12 12 if(content->tag == OPS_PTAG_CT_SECRET_KEY) … … 22 22 ops_secret_key_t *get_secret_key(const char *keyfile) 23 23 { 24 ops_reader_fd_arg_t arg; 25 ops_parse_info_t parse_info; 24 ops_parse_info_t *pinfo; 26 25 ops_secret_key_t *skey; 26 int fd; 27 27 28 ops_parse_info_init(&parse_info); 29 parse_info.cb=callback; 30 31 arg.fd=open(keyfile,O_RDONLY); 32 assert(arg.fd >= 0); 33 parse_info.reader_arg=&arg; 34 parse_info.reader=ops_reader_fd; 28 pinfo=ops_parse_info_new(); 35 29 36 30 skey=NULL; 37 parse_info.cb_arg=&skey;31 ops_parse_cb_set(pinfo,callback,&skey); 38 32 39 ops_parse(&parse_info); 33 fd=open(keyfile,O_RDONLY); 34 assert(fd >= 0); 35 ops_reader_set_fd(pinfo,fd); 36 37 ops_parse(pinfo); 40 38 41 39 return skey; openpgpsdk/trunk/examples/packet-dump.c
r313 r320 313 313 } 314 314 315 static ops_parse_c allback_return_t316 callback(const ops_parser_content_t *content_,void *arg_)315 static ops_parse_cb_return_t callback(const ops_parser_content_t *content_, 316 ops_parse_cb_info_t *cbinfo) 317 317 { 318 318 const ops_parser_content_union_t *content=&content_->content; … … 320 320 char *str; 321 321 322 OPS_USED( arg_);322 OPS_USED(cbinfo); 323 323 324 324 switch(content_->tag) … … 849 849 int main(int argc,char **argv) 850 850 { 851 ops_parse_info_t parse_info; 852 ops_reader_fd_arg_t arg; 851 ops_parse_info_t *pinfo; 853 852 ops_boolean_t armour=ops_false; 854 853 int ret; … … 874 873 875 874 876 ops_parse_info_init(&parse_info);875 pinfo=ops_parse_info_new(); 877 876 // ops_parse_packet_options(&opt,OPS_PTAG_SS_ALL,OPS_PARSE_RAW); 878 ops_parse_options(&parse_info,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED); 879 parse_info.cb=callback; 880 881 arg.fd=0; 882 parse_info.reader_arg=&arg; 883 parse_info.reader=ops_reader_fd; 877 ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED); 878 879 ops_parse_cb_set(pinfo,callback,NULL); 880 881 ops_reader_set_fd(pinfo,0); 884 882 885 883 if(armour) 886 { 887 parse_info.armour_allow_no_gap=ops_true; 888 parse_info.armour_allow_headers_without_gap=ops_true; 889 ops_reader_push_dearmour(&parse_info); 890 } 891 892 ret=ops_parse(&parse_info); 884 ops_reader_push_dearmour(pinfo,ops_true,ops_true); 885 886 ret=ops_parse(pinfo); 893 887 if (!ret) 894 {895 print_errors(parse_info.errors); 896 } 888 ops_print_errors(ops_parse_info_get_errors(pinfo)); 889 890 ops_parse_info_delete(pinfo); 897 891 898 892 return 0; openpgpsdk/trunk/examples/verify.c
r308 r320 11 11 int main(int argc,char **argv) 12 12 { 13 ops_parse_info_t parse_info;13 ops_parse_info_t *pinfo; 14 14 ops_keyring_t keyring; 15 ops_reader_fd_arg_t arg;16 15 const char *target; 16 int fd; 17 17 18 18 if(argc != 2) … … 27 27 28 28 memset(&keyring,'\0',sizeof keyring); 29 ops_parse_info_init(&parse_info); 30 arg.fd=open(target,O_RDONLY); 31 if(arg.fd < 0) 29 30 pinfo=ops_parse_info_new(); 31 32 fd=open(target,O_RDONLY); 33 if(fd < 0) 32 34 { 33 35 perror(target); 34 36 exit(2); 35 37 } 36 parse_info.reader_arg=&arg; 37 parse_info.reader=ops_reader_fd; 38 ops_reader_set_fd(pinfo,fd); 38 39 39 ops_parse_and_accumulate(&keyring, &parse_info);40 ops_parse_and_accumulate(&keyring,pinfo); 40 41 41 42 ops_dump_keyring(&keyring); openpgpsdk/trunk/examples/verify2.c
r318 r320 26 26 27 27 // FIXME: should this be a part of the library? 28 static ops_parse_c allback_return_t29 callback(const ops_parser_content_t *content_, void *arg_)28 static ops_parse_cb_return_t 29 callback(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 30 30 { 31 31 const ops_parser_content_union_t *content=&content_->content; 32 32 const ops_key_data_t *signer; 33 33 34 OPS_USED( arg_);34 OPS_USED(cbinfo); 35 35 36 36 switch(content_->tag) … … 122 122 int main(int argc,char **argv) 123 123 { 124 ops_parse_info_t parse_info;125 ops_reader_fd_arg_t arg;124 ops_parse_info_t *pinfo; 125 int fd; 126 126 const char *keyfile; 127 127 const char *verify; … … 153 153 154 154 memset(&keyring,'\0',sizeof keyring); 155 ops_parse_info_init(&parse_info); 156 157 arg.fd=open(keyfile,O_RDONLY); 158 if(arg.fd < 0) 155 156 pinfo=ops_parse_info_new(); 157 158 fd=open(keyfile,O_RDONLY); 159 if(fd < 0) 159 160 { 160 161 perror(keyfile); … … 162 163 } 163 164 164 parse_info.reader_arg=&arg; 165 parse_info.reader=ops_reader_fd; 166 167 ops_parse_and_accumulate(&keyring,&parse_info); 168 169 close(arg.fd); 165 ops_reader_set_fd(pinfo,fd); 166 167 ops_parse_and_accumulate(&keyring,pinfo); 168 169 close(fd); 170 170 171 171 if(verbose) 172 172 ops_dump_keyring(&keyring); 173 173 174 ops_parse_info_init(&parse_info); 175 176 arg.fd=open(verify,O_RDONLY); 177 if(arg.fd < 0) 174 ops_parse_info_delete(pinfo); 175 pinfo=ops_parse_info_new(); 176 177 fd=open(verify,O_RDONLY); 178 if(fd < 0) 178 179 { 179 180 perror(verify); … … 181 182 } 182 183 183 parse_info.reader_arg=&arg; 184 parse_info.reader=ops_reader_fd; 185 186 parse_info.cb=callback; 184 ops_reader_set_fd(pinfo,fd); 185 186 ops_parse_cb_set(pinfo,callback,NULL); 187 187 188 188 if(armour) 189 ops_reader_push_dearmour( &parse_info);190 191 ops_parse( &parse_info);189 ops_reader_push_dearmour(pinfo,ops_false,ops_false); 190 191 ops_parse(pinfo); 192 192 193 193 if(armour) 194 ops_reader_pop_dearmour( &parse_info);194 ops_reader_pop_dearmour(pinfo); 195 195 196 196 if(signed_data) openpgpsdk/trunk/include/openpgpsdk/armour.h
r314 r320 2 2 #include "signature.h" 3 3 4 void ops_reader_push_dearmour(ops_parse_info_t *parse_info); 4 void ops_reader_push_dearmour(ops_parse_info_t *parse_info, 5 ops_boolean_t without_gap,ops_boolean_t no_gap); 6 5 7 void ops_reader_pop_dearmour(ops_parse_info_t *parse_info); 6 8 void ops_writer_push_dash_escaped(ops_create_info_t *info, openpgpsdk/trunk/include/openpgpsdk/errors.h
r307 r320 49 49 char *ops_errcode(const ops_errcode_t errcode); 50 50 51 void push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno,51 void ops_push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, 52 52 const char *file,int line,const char *comment,...); 53 void print_error(ops_error_t *err);54 void print_errors(ops_error_t *errstack);53 void ops_print_error(ops_error_t *err); 54 void ops_print_errors(ops_error_t *errstack); 55 55 56 #define ops_system_error_1(err,code,syscall,fmt,arg) do { push_error(err,OPS_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,syscall);push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0)57 #define ops_error_1(err,code,fmt,arg) do {push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0)56 #define OPS_SYSTEM_ERROR_1(err,code,syscall,fmt,arg) do { ops_push_error(err,OPS_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,syscall); ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) 57 #define OPS_ERROR_1(err,code,fmt,arg) do { ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) 58 58 59 59 #endif /* OPS_ERRORS */ openpgpsdk/trunk/include/openpgpsdk/packet-parse.h
r287 r320 42 42 OPS_RELEASE_MEMORY, 43 43 OPS_KEEP_MEMORY 44 } ops_parse_c allback_return_t;44 } ops_parse_cb_return_t; 45 45 46 typedef ops_parse_callback_return_t 47 ops_packet_parse_callback_t(const ops_parser_content_t *content,void *arg); 46 typedef struct ops_parse_cb_info ops_parse_cb_info_t; 48 47 49 struct ops_parse_info; 50 typedef ops_reader_ret_t ops_packet_reader_t(unsigned char *dest, 51 unsigned *plength, 52 ops_reader_flags_t flags, 53 struct ops_parse_info *parse_info); 54 55 /** \brief Structure to hold information about a packet parse. 56 * 57 * This information includes options about the parse: 58 * - whether the packet contents should be accumulated or not 59 * - whether signature subpackets should be parsed or left raw 60 * 61 * It contains options specific to the parsing of armoured data: 62 * - whether headers are allowed in armoured data without a gap 63 * - whether a blank line is allowed at the start of the armoured data 64 * 65 * It also specifies : 66 * - the callback function to use and its arguments 67 * - the reader function to use and its arguments 68 * 69 * It also contains information about the current state of the parse: 70 * - offset from the beginning 71 * - the accumulated data, if any 72 * - the size of the buffer, and how much has been used 73 * 74 * It has a linked list of errors. 75 */ 76 77 struct ops_parse_info 78 { 79 unsigned char ss_raw[256/8]; /*!< one bit per signature-subpacket type; 80 set to get raw data */ 81 unsigned char ss_parsed[256/8]; /*!< one bit per signature-subpacket type; 82 set to get parsed data */ 83 84 ops_packet_parse_callback_t *cb; /*!< the callback function to use when parsing */ 85 void *cb_arg; /*!< the args to pass to the callback function */ 86 87 ops_packet_reader_t *reader; /*!< the reader function to use to get the data to be parsed */ 88 void *reader_arg; /*!< the args to pass to the reader function */ 89 /* XXX: what do we do about offsets into compressed packets? */ 90 unsigned position; /*!< the offset from the beginning (with this reader) */ 91 92 unsigned accumulate:1; /*!< set to accumulate packet data */ 93 unsigned char *accumulated; /*!< the accumulated data */ 94 unsigned asize; /*!< size of the buffer */ 95 unsigned alength; /*!< used buffer */ 96 unsigned armour_allow_headers_without_gap:1; /*!< allow headers in 97 armoured data that 98 are not separated 99 from the data by a 100 blank line */ 101 unsigned armour_allow_no_gap:1; /*!< allow no blank line at the 102 start of armoured data */ 103 ops_error_t * errors; 104 }; 48 typedef ops_parse_cb_return_t 49 ops_parse_cb_t(const ops_parser_content_t *content, 50 ops_parse_cb_info_t *cbinfo); 105 51 106 52 typedef struct ops_parse_info ops_parse_info_t; 53 typedef struct ops_reader_info ops_reader_info_t; 54 55 typedef ops_reader_ret_t ops_reader_t(unsigned char *dest, 56 unsigned *plength, 57 ops_reader_flags_t flags, 58 ops_error_t **errors, 59 ops_reader_info_t *rinfo, 60 ops_parse_cb_info_t *cbinfo); 61 typedef void ops_reader_destroyer_t(ops_reader_info_t *rinfo); 62 63 ops_parse_info_t *ops_parse_info_new(void); 64 void ops_parse_info_delete(ops_parse_info_t *pinfo); 65 ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo); 66 67 void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 68 void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 69 void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 70 void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 71 72 void *ops_reader_get_arg(ops_reader_info_t *rinfo); 73 void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo); 74 75 ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, 76 ops_parse_cb_info_t *cbinfo); 77 ops_parse_cb_return_t ops_parse_stacked_cb(const ops_parser_content_t *content, 78 ops_parse_cb_info_t *cbinfo); 79 ops_reader_info_t *ops_parse_get_rinfo(ops_parse_info_t *pinfo); 107 80 108 81 int ops_parse(ops_parse_info_t *parse_info); … … 121 94 }; 122 95 123 /** Initialise structure124 */125 #define ops_parse_info_init(parse_info) memset(parse_info,'\0',sizeof *parse_info)126 127 96 void ops_parse_options(ops_parse_info_t *parse_info,ops_content_tag_t tag, 128 97 ops_parse_type_t type); 129 98 130 int ops_limited_read(unsigned char *dest,unsigned length, 131 ops_region_t *region,ops_parse_info_t *parse_info); 99 ops_boolean_t ops_limited_read(unsigned char *dest,unsigned length, 100 ops_region_t *region,ops_error_t **errors, 101 ops_reader_info_t *rinfo, 102 ops_parse_cb_info_t *cbinfo); 103 ops_boolean_t ops_stacked_limited_read(unsigned char *dest,unsigned length, 104 ops_region_t *region, 105 ops_error_t **errors, 106 ops_reader_info_t *rinfo, 107 ops_parse_cb_info_t *cbinfo); 108 ops_reader_ret_t ops_stacked_read(unsigned char *dest,unsigned *length, 109 ops_reader_flags_t flags, 110 ops_error_t **errors, 111 ops_reader_info_t *rinfo, 112 ops_parse_cb_info_t *cbinfo); 132 113 133 114 /* vim:set textwidth=120: */ openpgpsdk/trunk/include/openpgpsdk/util.h
r307 r320 13 13 #define ops_true 1 14 14 15 /** Arguments for reader_fd16 */17 typedef struct18 {19 int fd; /*!< file descriptor */20 } ops_reader_fd_arg_t;21 22 15 void hexdump(const unsigned char *src,size_t length); 23 ops_reader_ret_t ops_reader_fd(unsigned char *dest,unsigned *plength, 24 ops_reader_flags_t flags,ops_parse_info_t *parse_info); 16 void ops_reader_set_fd(ops_parse_info_t *pinfo,int fd); 25 17 26 18 /* typesafe deconstification */ openpgpsdk/trunk/src/accumulate.c
r317 r320 7 7 #include <openpgpsdk/accumulate.h> 8 8 #include "keyring_local.h" 9 #include "parse_local.h" 9 10 #include <openpgpsdk/signature.h> 10 11 #include <assert.h> … … 14 15 typedef struct 15 16 { 16 ops_packet_parse_callback_t *cb;17 void *cb_arg;18 17 ops_keyring_t *keyring; 19 18 } accumulate_arg_t; … … 22 21 * \ingroup Callbacks 23 22 */ 24 static ops_parse_c allback_return_t25 accumulate_cb(const ops_parser_content_t *content_, void *arg_)23 static ops_parse_cb_return_t 24 accumulate_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 26 25 { 27 accumulate_arg_t *arg= arg_;26 accumulate_arg_t *arg=ops_parse_cb_get_arg(cbinfo); 28 27 const ops_parser_content_union_t *content=&content_->content; 29 28 ops_keyring_t *keyring=arg->keyring; … … 68 67 // XXX: we now exclude so many things, we should either drop this or 69 68 // do something to pass on copies of the stuff we keep 70 if(arg->cb) 71 return arg->cb(content_,arg->cb_arg); 72 return OPS_RELEASE_MEMORY; 69 return ops_parse_stacked_cb(content_,cbinfo); 73 70 } 74 71 … … 84 81 */ 85 82 86 void ops_parse_and_accumulate(ops_keyring_t *keyring,ops_parse_info_t *parse_info) 83 void ops_parse_and_accumulate(ops_keyring_t *keyring, 84 ops_parse_info_t *parse_info) 87 85 { 88 86 accumulate_arg_t arg; 89 87 90 assert(!parse_info-> accumulate);88 assert(!parse_info->rinfo.accumulate); 91 89 92 90 memset(&arg,'\0',sizeof arg); … … 95 93 /* Kinda weird, but to do with counting, and we put it back after */ 96 94 --keyring->nkeys; 97 arg.cb=parse_info->cb;98 arg.cb_arg=parse_info->cb_arg;99 95 100 parse_info->cb=accumulate_cb; 101 parse_info->cb_arg=&arg; 102 parse_info->accumulate=1; 96 ops_parse_cb_push(parse_info,accumulate_cb,&arg); 97 98 parse_info->rinfo.accumulate=ops_true; 99 103 100 ops_parse(parse_info); 104 101 ++keyring->nkeys; openpgpsdk/trunk/src/armour.c
r317 r320 15 15 typedef struct 16 16 { 17 ops_packet_reader_t *reader;18 void *reader_arg;19 17 enum 20 18 { … … 24 22 } state; 25 23 ops_parse_info_t *parse_info; 26 ops_boolean_t seen_nl; 27 ops_boolean_t prev_nl; 24 ops_boolean_t seen_nl:1; 25 ops_boolean_t prev_nl:1; 26 ops_boolean_t allow_headers_without_gap:1; /*!< allow headers in 27 armoured data that 28 are not separated 29 from the data by a 30 blank line */ 31 ops_boolean_t allow_no_gap:1; /*!< allow no blank line at the 32 start of armoured data */ 33 28 34 // base64 stuff 29 35 unsigned buffered; … … 43 49 44 50 // FIXME: move these to a common header 45 #define CB( t,pc) do { (pc)->tag=(t); if(arg->parse_info->cb(pc,arg->parse_info->cb_arg) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0)46 #define ERR( err) do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; arg->parse_info->cb(&content,arg->parse_info->cb_arg); return OPS_R_EARLY_EOF; } while(0)51 #define CB(cbinfo,t,pc) do { (pc)->tag=(t); if(ops_parse_cb((pc),(cbinfo)) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) 52 #define ERR(cbinfo,err) do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; ops_parse_cb(&content,(cbinfo)); return OPS_R_EARLY_EOF; } while(0) 47 53 48 54 static void push_back(dearmour_arg_t *arg,const unsigned char *buf, … … 58 64 } 59 65 60 static int read_char(dearmour_arg_t *arg,ops_boolean_t skip) 66 static int read_char(dearmour_arg_t *arg,ops_error_t **errors, 67 ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo, 68 ops_boolean_t skip) 61 69 { 62 70 unsigned char c[1]; 63 ops_packet_reader_t *reader;64 ops_reader_ret_t ret;65 71 unsigned length=1; 66 67 reader=arg->parse_info->reader;68 arg->parse_info->reader=arg->reader;69 arg->parse_info->reader_arg=arg->reader_arg;70 72 71 73 do … … 80 82 } 81 83 } 82 else if((ret=arg->reader(c,&length,0,arg->reader_arg)) != OPS_R_OK) 83 { 84 arg->parse_info->reader=reader; 85 arg->parse_info->reader_arg=arg; 86 84 /* XXX: should ops_stacked_read exist? Shouldn't this be a limited_read? */ 85 else if(ops_stacked_read(c,&length,0,errors,rinfo,cbinfo) != OPS_R_OK) 87 86 return -1; 88 }89 87 } 90 88 while(skip && c[0] == '\r'); 91 92 arg->parse_info->reader=reader;93 arg->parse_info->reader_arg=arg;94 89 95 90 arg->prev_nl=arg->seen_nl; … … 99 94 } 100 95 101 static void flush(dearmour_arg_t *arg )96 static void flush(dearmour_arg_t *arg,ops_parse_cb_info_t *cbinfo) 102 97 { 103 98 ops_parser_content_t content; … … 108 103 content.content.unarmoured_text.data=arg->unarmoured; 109 104 content.content.unarmoured_text.length=arg->num_unarmoured; 110 CB( OPS_PTAG_CT_UNARMOURED_TEXT,&content);105 CB(cbinfo,OPS_PTAG_CT_UNARMOURED_TEXT,&content); 111 106 arg->num_unarmoured=0; 112 107 } 113 108 114 static int unarmoured_read_char(dearmour_arg_t *arg,ops_boolean_t skip) 109 static int unarmoured_read_char(dearmour_arg_t *arg,ops_error_t **errors, 110 ops_reader_info_t *rinfo, 111 ops_parse_cb_info_t *cbinfo, 112 ops_boolean_t skip) 115 113 { 116 114 int c; … … 118 116 do 119 117 { 120 c=read_char(arg, ops_false);118 c=read_char(arg,errors,rinfo,cbinfo,ops_false); 121 119 if(c < 0) 122 120 return c; 123 121 arg->unarmoured[arg->num_unarmoured++]=c; 124 122 if(arg->num_unarmoured == sizeof arg->unarmoured) 125 flush(arg );123 flush(arg,cbinfo); 126 124 } 127 125 while(skip && c == '\r'); … … 156 154 /* Note that this skips CRs so implementations always see just 157 155 straight LFs as line terminators */ 158 static ops_reader_ret_t process_dash_escaped(dearmour_arg_t *arg) 156 static ops_reader_ret_t process_dash_escaped(dearmour_arg_t *arg, 157 ops_error_t **errors, 158 ops_reader_info_t *rinfo, 159 ops_parse_cb_info_t *cbinfo) 159 160 { 160 161 ops_parser_content_t content; … … 176 177 { 177 178 free(hash); 178 ERR( "Unknown hash algorithm");179 ERR(cbinfo,"Unknown hash algorithm"); 179 180 } 180 181 ops_hash_any(hash,alg); … … 191 192 unsigned count; 192 193 193 if((c=read_char(arg, ops_true)) < 0)194 if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 194 195 return OPS_R_EARLY_EOF; 195 196 if(arg->prev_nl && c == '-') 196 197 { 197 if((c=read_char(arg, ops_false)) < 0)198 if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 198 199 return OPS_R_EARLY_EOF; 199 200 if(c != ' ') … … 201 202 /* then this had better be a trailer! */ 202 203 if(c != '-') 203 ERR( "Bad dash-escaping");204 ERR(cbinfo,"Bad dash-escaping"); 204 205 for(count=2 ; count < 5 ; ++count) 205 206 { 206 if((c=read_char(arg, ops_false)) < 0)207 if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 207 208 return OPS_R_EARLY_EOF; 208 209 if(c != '-') 209 ERR( "Bad dash-escaping (2)");210 ERR(cbinfo,"Bad dash-escaping (2)"); 210 211 } 211 212 arg->state=AT_TRAILER_NAME; … … 213 214 } 214 215 /* otherwise we read the next character */ 215 if((c=read_char(arg, ops_false)) < 0)216 if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 216 217 return OPS_R_EARLY_EOF; 217 218 } … … 222 223 hash->add(hash,(unsigned char *)"\r",1); 223 224 hash->add(hash,body->data,body->length); 224 CB( OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content);225 CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 225 226 body->length=0; 226 227 } … … 229 230 if(body->length == sizeof body->data) 230 231 { 231 CB( OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content);232 CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 232 233 body->length=0; 233 234 } … … 239 240 240 241 trailer->hash=hash; 241 CB( OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER,&content2);242 CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER,&content2); 242 243 243 244 return OPS_R_OK; … … 255 256 } 256 257 257 static ops_reader_ret_t parse_headers(dearmour_arg_t *arg) 258 static ops_reader_ret_t parse_headers(dearmour_arg_t *arg,ops_error_t **errors, 259 ops_reader_info_t *rinfo, 260 ops_parse_cb_info_t *cbinfo) 258 261 { 259 262 char *buf; … … 270 273 int c; 271 274 272 if((c=read_char(arg, ops_true)) < 0)275 if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 273 276 return OPS_R_EARLY_EOF; 274 277 … … 285 288 s=strchr(buf,':'); 286 289 if(!s) 287 if(!first && !arg-> parse_info->armour_allow_headers_without_gap)290 if(!first && !arg->allow_headers_without_gap) 288 291 // then we have seriously malformed armour 289 ERR( "No colon in armour header");292 ERR(cbinfo,"No colon in armour header"); 290 293 else 291 294 { 292 295 if(first && 293 !(arg->parse_info->armour_allow_headers_without_gap 294 || arg->parse_info->armour_allow_no_gap)) 295 ERR("No colon in armour header (2)"); 296 !(arg->allow_headers_without_gap || arg->allow_no_gap)) 297 ERR(cbinfo,"No colon in armour header (2)"); 296 298 // then we have a nasty armoured block with no 297 299 // headers, not even a blank line. … … 304 306 *s='\0'; 305 307 if(s[1] != ' ') 306 ERR( "No space in armour header");308 ERR(cbinfo,"No space in armour header"); 307 309 add_header(arg,buf,s+2); 308 310 nbuf=0; … … 326 328 } 327 329 328 static ops_reader_ret_t read4(dearmour_arg_t *arg,int *pc,unsigned *pn, 330 static ops_reader_ret_t read4(dearmour_arg_t *arg,ops_error_t **errors, 331 ops_reader_info_t *rinfo, 332 ops_parse_cb_info_t *cbinfo,int *pc,unsigned *pn, 329 333 unsigned long *pl) 330 334 { … … 334 338 for(n=0 ; n < 4 ; ++n) 335 339 { 336 c=read_char(arg, ops_true);340 c=read_char(arg,errors,rinfo,cbinfo,ops_true); 337 341 if(c < 0) 338 342 { … … 383 387 } 384 388 385 static ops_reader_ret_t decode64(dearmour_arg_t *arg) 389 static ops_reader_ret_t decode64(dearmour_arg_t *arg,ops_error_t **errors, 390 ops_reader_info_t *rinfo, 391 ops_parse_cb_info_t *cbinfo) 386 392 { 387 393 unsigned n; … … 394 400 assert(arg->buffered == 0); 395 401 396 ret=read4(arg, &c,&n,&l);402 ret=read4(arg,errors,rinfo,cbinfo,&c,&n,&l); 397 403 if(ret != OPS_R_OK) 398 ERR( "Badly formed base64");404 ERR(cbinfo,"Badly formed base64"); 399 405 400 406 if(n == 3) … … 411 417 arg->eof64=ops_true; 412 418 l >>= 4; 413 c=read_char(arg, ops_false);419 c=read_char(arg,errors,rinfo,cbinfo,ops_false); 414 420 if(c != '=') 415 ERR( "Badly terminated base64");421 ERR(cbinfo,"Badly terminated base64"); 416 422 } 417 423 else if(n == 0) … … 431 437 // then we saw padding 432 438 assert(c == '='); 433 c=read_char(arg, ops_true);439 c=read_char(arg,errors,rinfo,cbinfo,ops_true); 434 440 if(c != '\n') 435 ERR( "No newline at base64 end");436 c=read_char(arg, ops_false);441 ERR(cbinfo,"No newline at base64 end"); 442 c=read_char(arg,errors,rinfo,cbinfo,ops_false); 437 443 if(c != '=') 438 ERR( "No checksum at base64 end");444 ERR(cbinfo,"No checksum at base64 end"); 439 445 } 440 446 … … 442 448 { 443 449 // now we are at the checksum 444 ret=read4(arg, &c,&n,&arg->read_checksum);450 ret=read4(arg,errors,rinfo,cbinfo,&c,&n,&arg->read_checksum); 445 451 if(ret != OPS_R_OK || n != 4) 446 ERR( "Error in checksum");447 c=read_char(arg, ops_true);452 ERR(cbinfo,"Error in checksum"); 453 c=read_char(arg,errors,rinfo,cbinfo,ops_true); 448 454 if(c != '\n') 449 ERR( "Badly terminated checksum");450 c=read_char(arg, ops_false);455 ERR(cbinfo,"Badly terminated checksum"); 456 c=read_char(arg,errors,rinfo,cbinfo,ops_false); 451 457 if(c != '-') 452 ERR( "Bad base64 trailer (2)");458 ERR(cbinfo,"Bad base64 trailer (2)"); 453 459 } 454 460 … … 456 462 { 457 463 for(n=0 ; n < 4 ; ++n) 458 if(read_char(arg, ops_false) != '-')459 ERR( "Bad base64 trailer");464 if(read_char(arg,errors,rinfo,cbinfo,ops_false) != '-') 465 ERR(cbinfo,"Bad base64 trailer"); 460 466 arg->eof64=ops_true; 461 467 } … … 473 479 474 480 if(arg->eof64 && arg->read_checksum != arg->checksum) 475 ERR( "Checksum mismatch");481 ERR(cbinfo,"Checksum mismatch"); 476 482 477 483 return OPS_R_OK; … … 493 499 unsigned *plength, 494 500 ops_reader_flags_t flags, 495 ops_parse_info_t *parse_info) 496 { 497 dearmour_arg_t *arg=parse_info->reader_arg; 498 unsigned length=*plength; 499 ops_parser_content_t content; 500 ops_reader_ret_t ret; 501 ops_boolean_t first; 502 503 OPS_USED(flags); 504 505 if(arg->eof64 && !arg->buffered) 506 assert(arg->state == OUTSIDE_BLOCK || arg->state == AT_TRAILER_NAME); 507 508 while(length > 0) 509 { 510 unsigned count; 511 unsigned n; 512 char buf[1024]; 513 int c; 514 515 flush(arg); 516 switch(arg->state) 517 { 518 case OUTSIDE_BLOCK: 519 /* This code returns EOF rather than EARLY_EOF because if 520 we don't see a header line at all, then it is just an 521 EOF (and not a BLOCK_END) */ 522 while(!arg->seen_nl) 523 if((c=unarmoured_read_char(arg,ops_true)) < 0) 524 return OPS_R_EOF; 525 526 /* flush at this point so we definitely have room for the 527 header, and so we can easily erase it from the buffer */ 528 flush(arg); 529 /* Find and consume the 5 leading '-' */ 530 for(count=0 ; count < 5 ; ++count) 531 { 532 if((c=unarmoured_read_char(arg,ops_false)) < 0) 533 return OPS_R_EOF; 534 if(c != '-') 535 goto reloop; 536 } 537 538 /* Now find the block type */ 539 for(n=0 ; n < sizeof buf-1 ; ) 540 { 541 if((c=unarmoured_read_char(arg,ops_false)) < 0) 542 return OPS_R_EOF; 543 if(c == '-') 544 goto got_minus; 545 buf[n++]=c; 546 } 547 /* then I guess this wasn't a proper header */ 548 break; 549 550 got_minus: 551 buf[n]='\0'; 552 553 /* Consume trailing '-' */ 554 for(count=1 ; count < 5 ; ++count) 555 { 556 if((c=unarmoured_read_char(arg,ops_false)) < 0) 557 return OPS_R_EOF; 558 if(c != '-') 559 /* wasn't a header after all */ 560 goto reloop; 561 } 562 563 /* Consume final NL */ 564 if((c=unarmoured_read_char(arg,ops_true)) < 0) 565 return OPS_R_EOF; 566 if(c != '\n') 567 /* wasn't a header line after all */ 568 break; 569 570 /* Now we've seen the header, scrub it from the buffer */ 571 arg->num_unarmoured=0; 572 573 /* But now we've seen a header line, then errors are 574 EARLY_EOF */ 575 if((ret=parse_headers(arg)) != OPS_R_OK) 576 return OPS_R_EARLY_EOF; 577 578 if(!strcmp(buf,"BEGIN PGP SIGNED MESSAGE")) 579 { 580 ops_reader_ret_t ret; 581 582 ops_dup_headers(&content.content.signed_cleartext_header.headers,&arg->headers); 583 CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER,&content); 584 585 ret=process_dash_escaped(arg); 586 if(ret != OPS_R_OK) 587 return ret; 588 } 589 else 590 { 591 content.content.armour_header.type=buf; 592 content.content.armour_header.headers=arg->headers; 593 memset(&arg->headers,'\0',sizeof arg->headers); 594 CB(OPS_PTAG_CT_ARMOUR_HEADER,&content); 595 base64(arg); 596 } 597 break; 598 599 case BASE64: 600 first=ops_true; 601 while(length > 0) 602 { 603 if(!arg->buffered) 604 { 605 if(!arg->eof64) 606 { 607 ret=decode64(arg); 608 if(ret != OPS_R_OK) 609 return ret; 610 } 611 if(!arg->buffered) 612 { 613 assert(arg->eof64); 614 if(first) 615 { 616 arg->state=AT_TRAILER_NAME; 617 goto reloop; 618 } 619 return OPS_R_EARLY_EOF; 620 } 621 } 622 623 assert(arg->buffered); 624 *dest=arg->buffer[--arg->buffered]; 625 ++dest; 626 --length; 627 first=ops_false; 628 } 629 if(arg->eof64 && !arg->buffered) 630 arg->state=AT_TRAILER_NAME; 631 break; 632 633 case AT_TRAILER_NAME: 634 for(n=0 ; n < sizeof buf-1 ; ) 635 { 636 if((c=read_char(arg,ops_false)) < 0) 637 return OPS_R_EARLY_EOF; 638 if(c == '-') 639 goto got_minus2; 640 buf[n++]=c; 641 } 642 /* then I guess this wasn't a proper trailer */ 643 ERR("Bad ASCII armour trailer"); 644 break; 645 646 got_minus2: 647 buf[n]='\0'; 648 649 /* Consume trailing '-' */ 650 for(count=1 ; count < 5 ; ++count) 651 { 652 if((c=read_char(arg,ops_false)) < 0) 653 return OPS_R_EARLY_EOF; 654 if(c != '-') 655 /* wasn't a trailer after all */ 656 ERR("Bad ASCII armour trailer (2)"); 657 } 658 659 /* Consume final NL */ 660 if((c=read_char(arg,ops_true)) < 0) 661 return OPS_R_EARLY_EOF; 662 if(c != '\n') 663 /* wasn't a trailer line after all */ 664 ERR("Bad ASCII armour trailer (3)"); 665 666 if(!strncmp(buf,"BEGIN ",6)) 667 { 668 if((ret=parse_headers(arg)) != OPS_R_OK) 669 return ret; 670 content.content.armour_header.type=buf; 671 content.content.armour_header.headers=arg->headers; 672 memset(&arg->headers,'\0',sizeof arg->headers); 673 CB(OPS_PTAG_CT_ARMOUR_HEADER,&content); 674 base64(arg); 675 } 676 else 677 { 678 content.content.armour_trailer.type=buf; 679 CB(OPS_PTAG_CT_ARMOUR_TRAILER,&content); 501 ops_error_t **errors, 502 ops_reader_info_t *rinfo, 503 ops_parse_cb_info_t *cbinfo) 504 { 505 dearmour_arg_t *arg=ops_reader_get_arg(rinfo); 506 unsigned length=*plength; 507 ops_parser_content_t content; 508 ops_reader_ret_t ret; 509 ops_boolean_t first; 510 511 OPS_USED(flags); 512 513 if(arg->eof64 && !arg->buffered) 514 assert(arg->state == OUTSIDE_BLOCK || arg->state == AT_TRAILER_NAME); 515 516 while(length > 0) 517 { 518 unsigned count; 519 unsigned n; 520 char buf[1024]; 521 int c; 522 523 flush(arg,cbinfo); 524 switch(arg->state) 525 { 526 case OUTSIDE_BLOCK: 527 /* This code returns EOF rather than EARLY_EOF because if 528 we don't see a header line at all, then it is just an 529 EOF (and not a BLOCK_END) */ 530 while(!arg->seen_nl) 531 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 532 return OPS_R_EOF; 533 534 /* flush at this point so we definitely have room for the 535 header, and so we can easily erase it from the buffer */ 536 flush(arg,cbinfo); 537 /* Find and consume the 5 leading '-' */ 538 for(count=0 ; count < 5 ; ++count) 539 { 540 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 541 return OPS_R_EOF; 542 if(c != '-') 543 goto reloop; 544 } 545 546 /* Now find the block type */ 547 for(n=0 ; n < sizeof buf-1 ; ) 548 { 549 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 550 return OPS_R_EOF; 551 if(c == '-') 552 goto got_minus; 553 buf[n++]=c; 554 } 555 /* then I guess this wasn't a proper header */ 556 break; 557 558 got_minus: 559 buf[n]='\0'; 560 561 /* Consume trailing '-' */ 562 for(count=1 ; count < 5 ; ++count) 563 { 564 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 565 return OPS_R_EOF; 566 if(c != '-') 567 /* wasn't a header after all */ 568 goto reloop; 569 } 570 571 /* Consume final NL */ 572 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 573 return OPS_R_EOF; 574 if(c != '\n') 575 /* wasn't a header line after all */ 576 break; 577 578 /* Now we've seen the header, scrub it from the buffer */ 579 arg->num_unarmoured=0; 580 581 /* But now we've seen a header line, then errors are 582 EARLY_EOF */ 583 if((ret=parse_headers(arg,errors,rinfo,cbinfo)) != OPS_R_OK) 584 return OPS_R_EARLY_EOF; 585 586 if(!strcmp(buf,"BEGIN PGP SIGNED MESSAGE")) 587 { 588 ops_reader_ret_t ret; 589 590 ops_dup_headers(&content.content.signed_cleartext_header.headers,&arg->headers); 591 CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER,&content); 592 593 ret=process_dash_escaped(arg,errors,rinfo,cbinfo); 594 if(ret != OPS_R_OK) 595 return ret; 596 } 597 else 598 { 599 content.content.armour_header.type=buf; 600 content.content.armour_header.headers=arg->headers; 601 memset(&arg->headers,'\0',sizeof arg->headers); 602 CB(cbinfo,OPS_PTAG_CT_ARMOUR_HEADER,&content); 603 base64(arg); 604 } 605 break; 606 607 case BASE64: 608 first=ops_true; 609 while(length > 0) 610 { 611 if(!arg->buffered) 612 { 613 if(!arg->eof64) 614 { 615 ret=decode64(arg,errors,rinfo,cbinfo); 616 if(ret != OPS_R_OK) 617 return ret; 618 } 619 if(!arg->buffered) 620 { 621 assert(arg->eof64); 622 if(first) 623 { 624 arg->state=AT_TRAILER_NAME; 625 goto reloop; 626 } 627 return OPS_R_EARLY_EOF; 628 } 629 } 630 631 assert(arg->buffered); 632 *dest=arg->buffer[--arg->buffered]; 633 ++dest; 634 --length; 635 first=ops_false; 636 } 637 if(arg->eof64 && !arg->buffered) 638 arg->state=AT_TRAILER_NAME; 639 break; 640 641 case AT_TRAILER_NAME: 642 for(n=0 ; n < sizeof buf-1 ; ) 643 { 644 if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 645 return OPS_R_EARLY_EOF; 646 if(c == '-') 647 goto got_minus2; 648 buf[n++]=c; 649 } 650 /* then I guess this wasn't a proper trailer */ 651 ERR(cbinfo,"Bad ASCII armour trailer"); 652 break; 653 654 got_minus2: 655 buf[n]='\0'; 656 657 /* Consume trailing '-' */ 658 for(count=1 ; count < 5 ; ++count) 659 { 660 if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 661 return OPS_R_EARLY_EOF; 662 if(c != '-') 663 /* wasn't a trailer after all */ 664 ERR(cbinfo,"Bad ASCII armour trailer (2)"); 665 } 666 667 /* Consume final NL */ 668 if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 669 return OPS_R_EARLY_EOF; 670 if(c != '\n') 671 /* wasn't a trailer line after all */ 672 ERR(cbinfo,"Bad ASCII armour trailer (3)"); 673 674 if(!strncmp(buf,"BEGIN ",6)) 675 { 676 if((ret=parse_headers(arg,errors,rinfo,cbinfo)) != OPS_R_OK) 677 return ret; 678 content.content.armour_header.type=buf; 679 content.content.armour_header.headers=arg->headers; 680 memset(&arg->headers,'\0',sizeof arg->headers); 681 CB(cbinfo,OPS_PTAG_CT_ARMOUR_HEADER,&content); 682 base64(arg); 683 } 684 else 685 { 686 content.content.armour_trailer.type=buf; 687 CB(cbinfo,OPS_PTAG_CT_ARMOUR_TRAILER,&content); 680 688 arg->state=OUTSIDE_BLOCK; 681 689 } … … 689 697 } 690 698 691 void ops_reader_push_dearmour(ops_parse_info_t *parse_info) 699 void ops_reader_push_dearmour(ops_parse_info_t *parse_info, 700 ops_boolean_t without_gap,ops_boolean_t no_gap) 692 701 { 693 702 dearmour_arg_t *arg; 694 703 695 704 arg=ops_mallocz(sizeof *arg); 696 697 arg->reader_arg=parse_info->reader_arg;698 arg->reader=parse_info->reader;699 arg->parse_info=parse_info;700 705 arg->seen_nl=ops_true; 701 702 parse_info->reader=armoured_data_reader; 703 parse_info->reader_arg=arg; 706 arg->allow_headers_without_gap=without_gap; 707 arg->allow_no_gap=no_gap; 708 709 ops_reader_push(parse_info,armoured_data_reader,arg); 704 710 } 705 711 706 712 void ops_reader_pop_dearmour(ops_parse_info_t *parse_info) 707 713 { 708 dearmour_arg_t *arg=parse_info->reader_arg; 709 710 parse_info->reader_arg=arg->reader_arg; 711 parse_info->reader=arg->reader; 714 dearmour_arg_t *arg=ops_reader_get_arg(ops_parse_get_rinfo(parse_info)); 712 715 713 716 free(arg); openpgpsdk/trunk/src/compress.c
r282 r320 11 11 typedef struct 12 12 { 13 ops_packet_reader_t *reader;14 void *reader_arg;15 ops_parse_info_t *parse_info;16 13 ops_region_t *region; 17 14 unsigned char in[DECOMPRESS_BUFFER]; … … 22 19 } decompress_arg_t; 23 20 24 #define ERR(err) do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; arg->parse_info->cb(&content,arg->parse_info->cb_arg); return OPS_R_EARLY_EOF; } while(0)21 #define ERR(err) do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; ops_parse_cb(&content,cbinfo); return OPS_R_EARLY_EOF; } while(0) 25 22 26 23 static ops_reader_ret_t compressed_data_reader(unsigned char *dest, 27 24 unsigned *plength, 28 25 ops_reader_flags_t flags, 29 ops_parse_info_t *parse_info) 26 ops_error_t **errors, 27 ops_reader_info_t *rinfo, 28 ops_parse_cb_info_t *cbinfo) 30 29 { 31 decompress_arg_t *arg= parse_info->reader_arg;30 decompress_arg_t *arg=ops_reader_get_arg(rinfo); 32 31 ops_parser_content_t content; 33 32 unsigned length=*plength; … … 71 70 n=sizeof arg->in; 72 71 73 arg->parse_info->reader=arg->reader; 74 arg->parse_info->reader_arg=arg->reader_arg; 75 76 if(!ops_limited_read(arg->in,n,arg->region,arg->parse_info)) 72 if(!ops_stacked_limited_read(arg->in,n,arg->region, 73 errors,rinfo,cbinfo)) 77 74 return OPS_R_EARLY_EOF; 78 79 arg->parse_info->reader=compressed_data_reader;80 arg->parse_info->reader_arg=arg;81 75 82 76 arg->stream.next_in=arg->in; … … 125 119 memset(&arg,'\0',sizeof arg); 126 120 127 arg.reader_arg=parse_info->reader_arg; 128 arg.reader=parse_info->reader; 121 129 122 arg.region=region; 130 arg.parse_info=parse_info;131 123 132 124 arg.stream.next_in=Z_NULL; … … 144 136 } 145 137 146 parse_info->reader=compressed_data_reader; 147 parse_info->reader_arg=&arg; 138 ops_reader_push(parse_info,compressed_data_reader,&arg); 148 139 149 140 return ops_parse(parse_info); openpgpsdk/trunk/src/create.c
r319 r320 567 567 if(n == -1) 568 568 { 569 ops_system_error_1(errors,OPS_E_W_WRITE_FAILED,"write",569 OPS_SYSTEM_ERROR_1(errors,OPS_E_W_WRITE_FAILED,"write", 570 570 "file descriptor %d",arg->fd); 571 571 return ops_false; … … 574 574 if((unsigned)n != length) 575 575 { 576 ops_error_1(errors,OPS_E_W_WRITE_TOO_SHORT,576 OPS_ERROR_1(errors,OPS_E_W_WRITE_TOO_SHORT, 577 577 "file descriptor %d",arg->fd); 578 578 return ops_false; openpgpsdk/trunk/src/errors.c
r307 r320 58 58 */ 59 59 60 void push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno,60 void ops_push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, 61 61 const char *file,int line,const char *fmt,...) 62 62 { … … 91 91 } 92 92 93 void print_error(ops_error_t *err)93 void ops_print_error(ops_error_t *err) 94 94 { 95 95 printf("%s:%d: ",err->file,err->line); 96 if (err->errcode==OPS_E_SYSTEM_ERROR)96 if(err->errcode==OPS_E_SYSTEM_ERROR) 97 97 printf("system error %d returned from %s()\n",err->sys_errno, 98 98 err->comment); … … 101 101 } 102 102 103 void print_errors(ops_error_t *errstack)103 void ops_print_errors(ops_error_t *errstack) 104 104 { 105 105 ops_error_t *err; 106 for (err=errstack; err!=NULL; err=err->next) 107 print_error(err); 106 107 for(err=errstack ; err!=NULL ; err=err->next) 108 ops_print_error(err); 108 109 } openpgpsdk/trunk/src/packet-parse.c
r313 r320 2 2 * \brief Parser for OpenPGP packets 3 3 */ 4 5 4 6 5 #include <openpgpsdk/packet.h> … … 9 8 #include <openpgpsdk/compress.h> 10 9 #include <openpgpsdk/errors.h> 10 #include "parse_local.h" 11 11 12 12 #include <assert.h> … … 39 39 return 0; 40 40 41 if (!ops_limited_read(data->contents, data->len,subregion,parse_info)) 41 if (!ops_limited_read(data->contents, data->len,subregion, 42 &parse_info->errors,&parse_info->rinfo, 43 &parse_info->cbinfo)) 42 44 return 0; 43 45 … … 70 72 */ 71 73 72 static int read_unsigned_string(unsigned char **str, ops_region_t *subregion, ops_parse_info_t *parse_info) 74 static int read_unsigned_string(unsigned char **str,ops_region_t *subregion, 75 ops_parse_info_t *pinfo) 73 76 { 74 77 int len=0; … … 80 83 return 0; 81 84 82 if(len && !ops_limited_read(*str,len,subregion,parse_info)) 85 if(len && !ops_limited_read(*str,len,subregion,&pinfo->errors, 86 &pinfo->rinfo,&pinfo->cbinfo)) 83 87 return 0; 84 88 … … 102 106 103 107 /*! \todo descr for CB macro */ 104 #define CB(t,pc) do { (pc)->tag=(t); if(parse_info->cb(pc,parse_info->cb_arg) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) 108 #define CB(cbinfo,t,pc) do { (pc)->tag=(t); if((cbinfo)->cb(pc,(cbinfo)->arg) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) 109 #define CBP(info,t,pc) CB(&(info)->cbinfo,t,pc) 105 110 /*! macro to save typing */ 106 111 #define C content.content 107 /*! macro to run CallBack function specifying a parser error has occurred */108 #define E CB(OPS_PARSER_ERROR,&content); return 0109 112 /*! set error code in content and run CallBack to handle error */ 110 #define ERRCODE( err) do { C.errcode.errcode=err; CB(OPS_PARSER_ERRCODE,&content); } while(0)113 #define ERRCODE(cbinfo,err) do { C.errcode.errcode=err; CB(cbinfo,OPS_PARSER_ERRCODE,&content); } while(0) 111 114 /*! set error text in content and run CallBack to handle error, then return */ 112 #define ERR(err) do { C.error.error=err; E; } while(0) 115 #define ERR(cbinfo,err) do { C.error.error=err; CB(cbinfo,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 116 #define ERRP(info,err) do { C.error.error=err; CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 113 117 /*! set error text in content and run CallBack to handle warning, do not return */ 114 118 #define WARN(warn) do { C.error.error=warn; CB(OPS_PARSER_ERROR,&content);; } while(0) 119 #define WARNP(info,warn) do { C.error.error=warn; CBP(info,OPS_PARSER_ERROR,&content); } while(0) 115 120 /*! \todo descr ERR1 macro */ 116 #define ERR1 (fmt,x) do { format_error(&content,(fmt),(x)); E; } while(0)121 #define ERR1P(info,fmt,x) do { format_error(&content,(fmt),(x)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 117 122 118 123 /* XXX: replace ops_ptag_t with something more appropriate for limiting … … 157 162 */ 158 163 164 static ops_reader_ret_t sub_base_read(unsigned char *dest,unsigned *plength, 165 ops_reader_flags_t flags, 166 ops_error_t **errors, 167 ops_reader_info_t *rinfo, 168 ops_parse_cb_info_t *cbinfo) 169 { 170 ops_reader_ret_t ret=rinfo->reader(dest,plength,flags,errors,rinfo,cbinfo); 171 172 if(ret != OPS_R_OK && ret != OPS_R_PARTIAL_READ) 173 return ret; 174 175 if(rinfo->accumulate) 176 { 177 assert(rinfo->asize >= rinfo->alength); 178 if(rinfo->alength+*plength > rinfo->asize) 179 { 180 rinfo->asize=rinfo->asize*2+*plength; 181 rinfo->accumulated=realloc(rinfo->accumulated,rinfo->asize); 182 } 183 assert(rinfo->asize >= rinfo->alength+*plength); 184 memcpy(rinfo->accumulated+rinfo->alength,dest,*plength); 185 } 186 // we track length anyway, because it is used for packet offsets 187 rinfo->alength+=*plength; 188 // and also the position 189 rinfo->position+=*plength; 190 191 return ret; 192 } 193 194 ops_reader_ret_t ops_stacked_read(unsigned char *dest,unsigned *length, 195 ops_reader_flags_t flags, 196 ops_error_t **errors, 197 ops_reader_info_t *rinfo, 198 ops_parse_cb_info_t *cbinfo) 199 { return sub_base_read(dest,length,flags,errors,rinfo->next,cbinfo); } 200 159 201 static ops_reader_ret_t base_read(unsigned char *dest,unsigned *plength, 160 202 ops_reader_flags_t flags, 161 ops_parse_info_t *parse_info) 162 { 163 ops_reader_ret_t ret=parse_info->reader(dest,plength,flags,parse_info); 164 if(ret != OPS_R_OK && ret != OPS_R_PARTIAL_READ) 165 return ret; 166 167 if(parse_info->accumulate) 168 { 169 assert(parse_info->asize >= parse_info->alength); 170 if(parse_info->alength+*plength > parse_info->asize) 171 { 172 parse_info->asize=parse_info->asize*2+*plength; 173 parse_info->accumulated=realloc(parse_info->accumulated,parse_info->asize); 174 } 175 assert(parse_info->asize >= parse_info->alength+*plength); 176 memcpy(parse_info->accumulated+parse_info->alength,dest,*plength); 177 } 178 // we track length anyway, because it is used for packet offsets 179 parse_info->alength+=*plength; 180 // and also the position 181 parse_info->position+=*plength; 182 183 return ret; 203 ops_parse_info_t *info) 204 { 205 return sub_base_read(dest,plength,flags,&info->errors,&info->rinfo, 206 &info->cbinfo); 184 207 } 185 208 … … 236 259 * \return 1 on success, 0 on error 237 260 */ 238 int ops_limited_read(unsigned char *dest,unsigned length, 239 ops_region_t *region,ops_parse_info_t *parse_info) 261 ops_boolean_t ops_limited_read(unsigned char *dest,unsigned length, 262 ops_region_t *region,ops_error_t **errors, 263 ops_reader_info_t *rinfo, 264 ops_parse_cb_info_t *cbinfo) 240 265 { 241 266 ops_parser_content_t content; … … 244 269 if(!region->indeterminate && region->length_read+length > region->length) 245 270 { 246 ERRCODE(OPS_E_P_NOT_ENOUGH_DATA); 247 return 0; 248 } 249 250 ret=base_read(dest,&length,region->indeterminate ? OPS_RETURN_LENGTH : 0, 251 parse_info); 271 ERRCODE(cbinfo,OPS_E_P_NOT_ENOUGH_DATA); 272 return 0; 273 } 274 275 ret=sub_base_read(dest,&length, 276 region->indeterminate ? OPS_RETURN_LENGTH : 0,errors, 277 rinfo,cbinfo); 252 278 253 279 if(ret != OPS_R_OK && ret != OPS_R_PARTIAL_READ) 254 280 { 255 ERRCODE( OPS_E_R_READ_FAILED);281 ERRCODE(cbinfo,OPS_E_R_READ_FAILED); 256 282 return 0; 257 283 } … … 266 292 267 293 return 1; 294 } 295 296 ops_boolean_t ops_stacked_limited_read(unsigned char *dest,unsigned length, 297 ops_region_t *region, 298 ops_error_t **errors, 299 ops_reader_info_t *rinfo, 300 ops_parse_cb_info_t *cbinfo) 301 { return ops_limited_read(dest,length,region,errors,rinfo->next,cbinfo); } 302 303 static ops_boolean_t limited_read(unsigned char *dest,unsigned length, 304 ops_region_t *region,ops_parse_info_t *info) 305 { 306 return ops_limited_read(dest,length,region,&info->errors,&info->rinfo, 307 &info->cbinfo); 268 308 } 269 309 … … 287 327 { 288 328 int n=length%8192; 289 if(! ops_limited_read(buf,n,region,parse_info))329 if(!limited_read(buf,n,region,parse_info)) 290 330 return 0; 291 331 length-=n; … … 320 360 assert(length <= 4); 321 361 assert(sizeof(*dest) >= 4); 322 if(! ops_limited_read(c,length,region,parse_info))362 if(!limited_read(c,length,region,parse_info)) 323 363 return 0; 324 364 … … 430 470 431 471 assert(length <= 8192); 432 if(! ops_limited_read(buf,length,region,parse_info))472 if(!limited_read(buf,length,region,parse_info)) 433 473 return 0; 434 474 435 475 if((buf[0] >> nonzero) != 0 || !(buf[0]&(1 << (nonzero-1)))) 436 ERR ("MPI format error"); /* XXX: Ben, one part of this constraint does not apply to encrypted MPIs the draft says. -- peter */476 ERRP(parse_info,"MPI format error"); /* XXX: Ben, one part of this constraint does not apply to encrypted MPIs the draft says. -- peter */ 437 477 438 478 *pbn=BN_bin2bn(buf,length,NULL); … … 496 536 unsigned char c[1]; 497 537 498 if(! ops_limited_read(c,1,region,parse_info))538 if(!limited_read(c,1,region,parse_info)) 499 539 return 0; 500 540 if(c[0] < 192) … … 507 547 unsigned t=(c[0]-192) << 8; 508 548 509 if(! ops_limited_read(c,1,region,parse_info))549 if(!limited_read(c,1,region,parse_info)) 510 550 return 0; 511 551 *length=t+c[0]+192; … … 741 781 assert (region->length_read == 0); /* We should not have read anything so far */ 742 782 743 if(! ops_limited_read(c,1,region,parse_info))783 if(!limited_read(c,1,region,parse_info)) 744 784 return 0; 745 785 key->version=c[0]; 746 786 if(key->version < 2 || key->version > 4) 747 ERR1 ("Bad public key version (0x%02x)",key->version);787 ERR1P(parse_info,"Bad public key version (0x%02x)",key->version); 748 788 749 789 if(!limited_read_time(&key->creation_time,region,parse_info)) … … 755 795 return 0; 756 796 757 if(! ops_limited_read(c,1,region,parse_info))797 if(!limited_read(c,1,region,parse_info)) 758 798 return 0; 759 799 … … 787 827 788 828 default: 789 ERR1 ("Unknown public key algorithm (%d)",key->algorithm);829 ERR1P(parse_info,"Unknown public key algorithm (%d)",key->algorithm); 790 830 } 791 831 … … 817 857 // XXX: this test should be done for all packets, surely? 818 858 if(region->length_read != region->length) 819 ERR1("Unconsumed data (%d)",region->length-region->length_read); 820 821 CB(tag,&content); 859 ERR1P(parse_info,"Unconsumed data (%d)", 860 region->length-region->length_read); 861 862 CBP(parse_info,tag,&content); 822 863 823 864 return 1; … … 868 909 return 0; 869 910 870 CB (OPS_PTAG_CT_USER_ATTRIBUTE,&content);911 CBP(parse_info,OPS_PTAG_CT_USER_ATTRIBUTE,&content); 871 912 872 913 return 1; … … 905 946 C.user_id.user_id=malloc(region->length+1); /* XXX should we not like check malloc's return value? */ 906 947 907 if(region->length && ! ops_limited_read(C.user_id.user_id,region->length,908 region,parse_info))948 if(region->length && !limited_read(C.user_id.user_id,region->length,region, 949 parse_info)) 909 950 return 0; 910 951 911 952 C.user_id.user_id[region->length]='\0'; /* terminate the string */ 912 953 913 CB (OPS_PTAG_CT_USER_ID,&content);954 CBP(parse_info,OPS_PTAG_CT_USER_ID,&content); 914 955 915 956 return 1; … … 986 1027 * \see RFC2440bis-12 5.2.2 987 1028 */ 988 static int parse_v3_signature(ops_region_t *region,ops_parse_info_t *parse_info) 1029 static int parse_v3_signature(ops_region_t *region, 1030 ops_parse_info_t *parse_info) 989 1031 { 990 1032 unsigned char c[1]; … … 994 1036 995 1037 /* hash info length */ 996 if(! ops_limited_read(c,1,region,parse_info))1038 if(!limited_read(c,1,region,parse_info)) 997 1039 return 0; 998 1040 if(c[0] != 5) 999 ERR ("bad hash info length");1000 1001 if(! ops_limited_read(c,1,region,parse_info))1041 ERRP(parse_info,"bad hash info length"); 1042 1043 if(!limited_read(c,1,region,parse_info)) 1002 1044 return 0; 1003 1045 C.signature.type=c[0]; … … 1008 1050 C.signature.creation_time_set=ops_true; 1009 1051 1010 if(! ops_limited_read(C.signature.signer_id,OPS_KEY_ID_SIZE,region,parse_info))1052 if(!limited_read(C.signature.signer_id,OPS_KEY_ID_SIZE,region,parse_info)) 1011 1053 return 0; 1012 1054 C.signature.signer_id_set=ops_true; 1013 1055 1014 if(! ops_limited_read(c,1,region,parse_info))1056 if(!limited_read(c,1,region,parse_info)) 1015 1057 return 0; 1016 1058 C.signature.key_algorithm=c[0]; 1017 1059 /* XXX: check algorithm */ 1018 1060 1019 if(! ops_limited_read(c,1,region,parse_info))1061 if(!limited_read(c,1,region,parse_info)) 1020 1062 return 0; 1021 1063 C.signature.hash_algorithm=c[0]; 1022 1064 /* XXX: check algorithm */ 1023 1065 1024 if(! ops_limited_read(C.signature.hash2,2,region,parse_info))1066 if(!limited_read(C.signature.hash2,2,region,parse_info)) 1025 1067 return 0; 1026 1068 … … 1046 1088 1047 1089 default: 1048 ERR1 ("Bad signature key algorithm (%d)",C.signature.key_algorithm);1090 ERR1P(parse_info,"Bad signature key algorithm (%d)",C.signature.key_algorithm); 1049 1091 } 1050 1092 1051 1093 if(region->length_read != region->length) 1052 ERR1 ("Unconsumed data (%d)",region->length-region->length_read);1053 1054 CB (OPS_PTAG_CT_SIGNATURE,&content);1094 ERR1P(parse_info,"Unconsumed data (%d)",region->length-region->length_read); 1095 1096 CBP(parse_info,OPS_PTAG_CT_SIGNATURE,&content); 1055 1097 1056 1098 return 1; … … 1089 1131 1090 1132 if(subregion.length > region->length) 1091 ERR ("Subpacket too long");1092 1093 if(! ops_limited_read(c,1,&subregion,parse_info))1133 ERRP(parse_info,"Subpacket too long"); 1134 1135 if(!limited_read(c,1,&subregion,parse_info)) 1094 1136 return 0; 1095 1137 … … 1106 1148 C.ss_raw.length=subregion.length-1; 1107 1149 C.ss_raw.raw=malloc(C.ss_raw.length); 1108 if(! ops_limited_read(C.ss_raw.raw,C.ss_raw.length,&subregion,parse_info))1109 return 0; 1110 CB (OPS_PTAG_RAW_SS,&content);1150 if(!limited_read(C.ss_raw.raw,C.ss_raw.length,&subregion,parse_info)) 1151 return 0; 1152 CBP(parse_info,OPS_PTAG_RAW_SS,&content); 1111 1153 return 1; 1112 1154 } … … 1127 1169 1128 1170 case OPS_PTAG_SS_TRUST: 1129 if(! ops_limited_read(&C.ss_trust.level,1,&subregion,parse_info)1130 || ! ops_limited_read(&C.ss_trust.amount,1,&subregion,parse_info))1171 if(!limited_read(&C.ss_trust.level,1,&subregion,parse_info) 1172 || !limited_read(&C.ss_trust.amount,1,&subregion,parse_info)) 1131 1173 return 0; 1132 1174 break; 1133 1175 1134 1176 case OPS_PTAG_SS_REVOCABLE: 1135 if(! ops_limited_read(bool,1,&subregion,parse_info))1177 if(!limited_read(bool,1,&subregion,parse_info)) 1136 1178 return 0; 1137 1179 C.ss_revocable.revocable=!!bool; … … 1139 1181 1140 1182 case OPS_PTAG_SS_ISSUER_KEY_ID: 1141 if(! ops_limited_read(C.ss_issuer_key_id.key_id,OPS_KEY_ID_SIZE,1183 if(!limited_read(C.ss_issuer_key_id.key_id,OPS_KEY_ID_SIZE, 1142 1184 &subregion,parse_info)) 1143 1185 return 0; … … 1162 1204 1163 1205 case OPS_PTAG_SS_PRIMARY_USER_ID: 1164 if(! ops_limited_read (bool,1,&subregion,parse_info))1206 if(!limited_read (bool,1,&subregion,parse_info)) 1165 1207 return 0; 1166 1208 C.ss_primary_user_id.primary_user_id = !!bool; … … 1241 1283 case OPS_PTAG_SS_REVOCATION_REASON: 1242 1284 /* first byte is the machine-readable code */ 1243 if(! ops_limited_read(&C.ss_revocation_reason.code,1,&subregion,parse_info))1285 if(!limited_read(&C.ss_revocation_reason.code,1,&subregion,parse_info)) 1244 1286 return 0; 1245 1287 … … 1251 1293 case OPS_PTAG_SS_REVOCATION_KEY: 1252 1294 /* octet 0 = class. Bit 0x80 must be set */ 1253 if(! ops_limited_read (&C.ss_revocation_key.class,1,&subregion,parse_info))1295 if(!limited_read (&C.ss_revocation_key.class,1,&subregion,parse_info)) 1254 1296 return 0; 1255 1297 if(!(C.ss_revocation_key.class&0x80)) … … 1261 1303 1262 1304 /* octet 1 = algid */ 1263 if(! ops_limited_read(&C.ss_revocation_key.algid,1,&subregion,parse_info))1305 if(!limited_read(&C.ss_revocation_key.algid,1,&subregion,parse_info)) 1264 1306 return 0; 1265 1307 1266 1308 /* octets 2-21 = fingerprint */ 1267 if(! ops_limited_read(&C.ss_revocation_key.fingerprint[0],20,&subregion,1268 parse_info))1309 if(!limited_read(&C.ss_revocation_key.fingerprint[0],20,&subregion, 1310 parse_info)) 1269 1311 return 0; 1270 1312 break; … … 1272 1314 default: 1273 1315 if(parse_info->ss_parsed[t8]&t7) 1274 ERR1("Unknown signature subpacket type (%d)",c[0]&0x7f); 1316 ERR1P(parse_info,"Unknown signature subpacket type (%d)", 1317 c[0]&0x7f); 1275 1318 read=ops_false; 1276 1319 break; … … 1281 1324 { 1282 1325 if(content.critical) 1283 ERR1("Critical signature subpacket ignored (%d)",c[0]&0x7f); 1326 ERR1P(parse_info,"Critical signature subpacket ignored (%d)", 1327 c[0]&0x7f); 1284 1328 if(!read && !limited_skip(subregion.length-1,&subregion,parse_info)) 1285 1329 return 0; … … 1291 1335 1292 1336 if(read && subregion.length_read != subregion.length) 1293 ERR1 ("Unconsumed data (%d)", subregion.length-subregion.length_read);1337 ERR1P(parse_info,"Unconsumed data (%d)", subregion.length-subregion.length_read); 1294 1338 1295 CB (content.tag,&content);1339 CBP(parse_info,content.tag,&content); 1296 1340 1297 1341 return 1; … … 1361 1405 1362 1406 if(subregion.length > region->length) 1363 ERR ("Subpacket set too long");1407 ERRP(parse_info,"Subpacket set too long"); 1364 1408 1365 1409 while(subregion.length_read < subregion.length) … … 1371 1415 if(!limited_skip(subregion.length-subregion.length_read,&subregion, 1372 1416 parse_info)) 1373 ERR ("Read failed while recovering from subpacket length mismatch");1374 ERR ("Subpacket length mismatch");1417 ERRP(parse_info,"Read failed while recovering from subpacket length mismatch"); 1418 ERRP(parse_info,"Subpacket length mismatch"); 1375 1419 } 1376 1420 … … 1401 1445 C.signature.v4_hashed_data_start=v4_hashed_data_start; 1402 1446 1403 if(! ops_limited_read(c,1,region,parse_info))1447 if(!limited_read(c,1,region,parse_info)) 1404 1448 return 0; 1405 1449 C.signature.type=c[0]; 1406 1450 /* XXX: check signature type */ 1407 1451 1408 if(! ops_limited_read(c,1,region,parse_info))1452 if(!limited_read(c,1,region,parse_info)) 1409 1453 return 0; 1410 1454 C.signature.key_algorithm=c[0]; 1411 1455 /* XXX: check algorithm */ 1412 1456 1413 if(! ops_limited_read(c,1,region,parse_info))1457 if(!limited_read(c,1,region,parse_info)) 1414 1458 return 0; 1415 1459 C.signature.hash_algorithm=c[0]; 1416 1460 /* XXX: check algorithm */ 1417 1461 1418 CB (OPS_PTAG_CT_SIGNATURE_HEADER,&content);1462 CBP(parse_info,OPS_PTAG_CT_SIGNATURE_HEADER,&content); 1419 1463 1420 1464 if(!parse_signature_subpackets(&C.signature,region,parse_info)) 1421 1465 return 0; 1422 C.signature.v4_hashed_data_length=parse_info-> alength1466 C.signature.v4_hashed_data_length=parse_info->rinfo.alength 1423 1467 -C.signature.v4_hashed_data_start; 1424 1468 … … 1426 1470 return 0; 1427 1471 1428 if(! ops_limited_read(C.signature.hash2,2,region,parse_info))1472 if(!limited_read(C.signature.hash2,2,region,parse_info)) 1429 1473 return 0; 1430 1474 … … 1438 1482 case OPS_PKA_DSA: 1439 1483 if(!limited_read_mpi(&C.signature.signature.dsa.r,region,parse_info)) 1440 ERR ("Error reading DSA r field in signature");1484 ERRP(parse_info,"Error reading DSA r field in signature"); 1441 1485 if (!limited_read_mpi(&C.signature.signature.dsa.s,region,parse_info)) 1442 ERR ("Error reading DSA s field in signature");1486 ERRP(parse_info,"Error reading DSA s field in signature"); 1443 1487 break; 1444 1488 … … 1465 1509 1466 1510 default: 1467 ERR1("Bad v4 signature key algorithm (%d)",C.signature.key_algorithm); 1511 ERR1P(parse_info,"Bad v4 signature key algorithm (%d)", 1512 C.signature.key_algorithm); 1468 1513 } 1469 1514 1470 1515 if(region->length_read != region->length) 1471 ERR1("Unconsumed data (%d)",region->length-region->length_read); 1472 1473 CB(OPS_PTAG_CT_SIGNATURE_FOOTER,&content); 1516 ERR1P(parse_info,"Unconsumed data (%d)", 1517 region->length-region->length_read); 1518 1519 CBP(parse_info,OPS_PTAG_CT_SIGNATURE_FOOTER,&content); 1474 1520 1475 1521 return 1; … … 1497 1543 memset(&content,'\0',sizeof content); 1498 1544 1499 v4_hashed_data_start=parse_info->alength; 1500 if(!ops_limited_read(c,1,region,parse_info)) 1501 return 0; 1502 1503 /* XXX: More V2 issues! - Ben*/ 1504 /* XXX: are there v2 signatures? - Peter */ 1545 v4_hashed_data_start=parse_info->rinfo.alength; 1546 if(!limited_read(c,1,region,parse_info)) 1547 return 0; 1548 1505 1549 if(c[0] == 2 || c[0] == 3) 1506 1550 return parse_v3_signature(region,parse_info); 1507 1551 else if(c[0] == 4) 1508 1552 return parse_v4_signature(region,parse_info,v4_hashed_data_start); 1509 ERR1 ("Bad signature version (%d)",c[0]);1553 ERR1P(parse_info,"Bad signature version (%d)",c[0]); 1510 1554 } 1511 1555 … … 1515 1559 ops_parser_content_t content; 1516 1560 1517 if(! ops_limited_read(c,1,region,parse_info))1561 if(!limited_read(c,1,region,parse_info)) 1518 1562 return 0; 1519 1563 1520 1564 C.compressed.type=c[0]; 1521 1565 1522 CB (OPS_PTAG_CT_COMPRESSED,&content);1566 CBP(parse_info,OPS_PTAG_CT_COMPRESSED,&content); 1523 1567 1524 1568 /* The content of a compressed data packet is more OpenPGP packets … … 1533 1577 ops_parser_content_t content; 1534 1578 1535 if(! ops_limited_read(&C.one_pass_signature.version,1,region,parse_info))1579 if(!limited_read(&C.one_pass_signature.version,1,region,parse_info)) 1536 1580 return 0; 1537 1581 if(C.one_pass_signature.version != 3) 1538 ERR1 ("Bad one-pass signature version (%d)",1582 ERR1P(parse_info,"Bad one-pass signature version (%d)", 1539 1583 C.one_pass_signature.version); 1540 1584 1541 if(! ops_limited_read(c,1,region,parse_info))1585 if(!limited_read(c,1,region,parse_info)) 1542 1586 return 0; 1543 1587 C.one_pass_signature.sig_type=c[0]; 1544 1588 1545 if(! ops_limited_read(c,1,region,parse_info))1589 if(!limited_read(c,1,region,parse_info)) 1546 1590 return 0; 1547 1591 C.one_pass_signature.hash_algorithm=c[0]; 1548 1592 1549 if(! ops_limited_read(c,1,region,parse_info))1593 if(!limited_read(c,1,region,parse_info)) 1550 1594 return 0; 1551 1595 C.one_pass_signature.key_algorithm=c[0]; 1552 1596 1553 if(! ops_limited_read(C.one_pass_signature.keyid,1597 if(!limited_read(C.one_pass_signature.keyid, 1554 1598 sizeof C.one_pass_signature.keyid,region,parse_info)) 1555 1599 return 0; 1556 1600 1557 if(! ops_limited_read(c,1,region,parse_info))1601 if(!limited_read(c,1,region,parse_info)) 1558 1602 return 0; 1559 1603 C.one_pass_signature.nested=!!c[0]; 1560 1604 1561 CB (OPS_PTAG_CT_ONE_PASS_SIGNATURE,&content);1605 CBP(parse_info,OPS_PTAG_CT_ONE_PASS_SIGNATURE,&content); 1562 1606 1563 1607 return 1; … … 1603 1647 return 0; 1604 1648 1605 CB (OPS_PTAG_CT_TRUST, &content);1649 CBP(parse_info,OPS_PTAG_CT_TRUST, &content); 1606 1650 1607 1651 return 1; … … 1613 1657 unsigned char c[1]; 1614 1658 1615 if(! ops_limited_read(c,1,region,parse_info))1659 if(!limited_read(c,1,region,parse_info)) 1616 1660 return 0; 1617 1661 C.literal_data_header.format=c[0]; 1618 1662 1619 if(!ops_limited_read(c,1,region,parse_info)) 1620 return 0; 1621 if(!ops_limited_read((unsigned char *)C.literal_data_header.filename,c[0],region,parse_info)) 1663 if(!limited_read(c,1,region,parse_info)) 1664 return 0; 1665 if(!limited_read((unsigned char *)C.literal_data_header.filename,c[0], 1666 region,parse_info)) 1622 1667 return 0; 1623 1668 C.literal_data_header.filename[c[0]]='\0'; … … 1626 1671 return 0; 1627 1672 1628 CB (OPS_PTAG_CT_LITERAL_DATA_HEADER,&content);1673 CBP(parse_info,OPS_PTAG_CT_LITERAL_DATA_HEADER,&content); 1629 1674 1630 1675 while(region->length_read < region->length) … … 1635 1680 l=sizeof C.literal_data_body.data; 1636 1681 1637 if(! ops_limited_read(C.literal_data_body.data,l,region,parse_info))1682 if(!limited_read(C.literal_data_body.data,l,region,parse_info)) 1638 1683 return 0; 1639 1684 1640 1685 C.literal_data_body.length=l; 1641 1686 1642 CB (OPS_PTAG_CT_LITERAL_DATA_BODY,&content);1687 CBP(parse_info,OPS_PTAG_CT_LITERAL_DATA_BODY,&content); 1643 1688 } 1644 1689 … … 1682 1727 if(!parse_public_key_data(&C.secret_key.public_key,region,parse_info)) 1683 1728 return 0; 1684 if(! ops_limited_read(c,1,region,parse_info))1729 if(!limited_read(c,1,region,parse_info)) 1685 1730 return 0; 1686 1731 C.secret_key.s2k_usage=c[0]; … … 1707 1752 // XXX: check the checksum 1708 1753 1709 CB (OPS_PTAG_CT_SECRET_KEY,&content);1754 CBP(parse_info,OPS_PTAG_CT_SECRET_KEY,&content); 1710 1755 1711 1756 return 1; … … 1721 1766 * \param *pktlen On return, will contain number of bytes in packet 1722 1767 * \return 1 on success, 0 on error, -1 on EOF */ 1723 static int ops_parse_one_packet(ops_parse_info_t *parse_info,unsigned long *pktlen) 1768 static int ops_parse_one_packet(ops_parse_info_t *parse_info, 1769 unsigned long *pktlen) 1724 1770 { 1725 1771 unsigned char ptag[1]; … … 1731 1777 ops_boolean_t indeterminate=ops_false; 1732 1778 1733 C.ptag.position=parse_info-> position;1779 C.ptag.position=parse_info->rinfo.position; 1734 1780 1735 1781 ret=base_read(ptag,&one,0,parse_info); … … 1743 1789 { 1744 1790 C.error.error="Format error (ptag bit not set)"; 1745 CB (OPS_PARSER_ERROR,&content);1791 CBP(parse_info,OPS_PARSER_ERROR,&content); 1746 1792 return 0; 1747 1793 } … … 1784 1830 } 1785 1831 1786 CB (OPS_PARSER_PTAG,&content);1832 CBP(parse_info,OPS_PARSER_PTAG,&content); 1787 1833 1788 1834 ops_init_subregion(®ion,NULL); … … 1831 1877 format_error(&content,"Format error (unknown content tag %d)", 1832 1878 C.ptag.content_tag); 1833 CB (OPS_PARSER_ERROR,&content);1879 CBP(parse_info,OPS_PARSER_ERROR,&content); 1834 1880 r=0; 1835 1881 } … … 1846 1892 /* now throw it away */ 1847 1893 data_free(&remainder); 1848 WARN ("Remainder of packet consumed and discarded.");1894 WARNP(parse_info,"Remainder of packet consumed and discarded."); 1849 1895 } 1850 1896 else 1851 WARN ("Problem consuming remainder of error packet.");1897 WARNP(parse_info,"Problem consuming remainder of error packet."); 1852 1898 } 1853 1899 1854 1900 /* set pktlen */ 1855 1901 1856 *pktlen=parse_info-> alength;1902 *pktlen=parse_info->rinfo.alength; 1857 1903 1858 1904 /* do callback on entire packet, if desired */ 1859 1905 1860 if(parse_info-> accumulate)1861 { 1862 C.packet.length=parse_info-> alength;1863 C.packet.raw=parse_info-> accumulated;1864 parse_info-> accumulated=NULL;1865 parse_info-> asize=0;1866 CB (OPS_PARSER_PACKET_END,&content);1867 } 1868 parse_info-> alength=0;1906 if(parse_info->rinfo.accumulate) 1907 { 1908 C.packet.length=parse_info->rinfo.alength; 1909 C.packet.raw=parse_info->rinfo.accumulated; 1910 parse_info->rinfo.accumulated=NULL; 1911 parse_info->rinfo.asize=0; 1912 CBP(parse_info,OPS_PARSER_PACKET_END,&content); 1913 } 1914 parse_info->rinfo.alength=0; 1869 1915 1870 1916 return r ? 1 : 0; … … 1908 1954 } 1909 1955 1956 #if 0 1910 1957 /** 1911 1958 * … … 1924 1971 /* can only handle ops_reader_fd for now */ 1925 1972 1926 if (parse_info->r eader != ops_reader_fd)1973 if (parse_info->rinfo.reader != ops_reader_fd) 1927 1974 { 1928 1975 fprintf(stderr,"ops_parse_errs: can only handle ops_reader_fd\n"); … … 1930 1977 } 1931 1978 1932 arg=parse_info->r eader_arg;1979 arg=parse_info->rinfo.arg; 1933 1980 1934 1981 /* store current state of accumulate flag */ 1935 1982 1936 orig_acc=parse_info-> accumulate;1983 orig_acc=parse_info->rinfo.accumulate; 1937 1984 1938 1985 /* set accumulate flag */ 1939 1986 1940 parse_info-> accumulate=1;1987 parse_info->rinfo.accumulate=1; 1941 1988 1942 1989 /* now parse each error in turn. */ … … 1963 2010 1964 2011 /* restore accumulate flag original value */ 1965 parse_info-> accumulate=orig_acc;2012 parse_info->rinfo.accumulate=orig_acc; 1966 2013 1967 2014 return 1; 1968 2015 } 2016 #endif 1969 2017 1970 2018 /** … … 2017 2065 } 2018 2066 2067 ops_parse_info_t *ops_parse_info_new(void) 2068 { return ops_mallocz(sizeof(ops_parse_info_t)); } 2069 2070 void ops_parse_info_delete(ops_parse_info_t *pinfo) 2071 { free(pinfo); } 2072 2073 ops_reader_info_t *ops_parse_get_rinfo(ops_parse_info_t *pinfo) 2074 { return &pinfo->rinfo; } 2075 2076 void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg) 2077 { 2078 pinfo->cbinfo.cb=cb; 2079 pinfo->cbinfo.arg=arg; 2080 } 2081 2082 void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg) 2083 { 2084 ops_parse_cb_info_t *cbinfo=malloc(sizeof *cbinfo); 2085 2086 *cbinfo=pinfo->cbinfo; 2087 pinfo->cbinfo.next=cbinfo; 2088 ops_parse_cb_set(pinfo,cb,arg); 2089 } 2090 2091 void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo) 2092 { return cbinfo->arg; } 2093 2094 ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, 2095 ops_parse_cb_info_t *cbinfo) 2096 { return cbinfo->cb(content,cbinfo); } 2097 2098 ops_parse_cb_return_t ops_parse_stacked_cb(const ops_parser_content_t *content, 2099 ops_parse_cb_info_t *cbinfo) 2100 { return ops_parse_cb(content,cbinfo->next); } 2101 2102 void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg) 2103 { 2104 pinfo->rinfo.reader=reader; 2105 pinfo->rinfo.arg=arg; 2106 } 2107 2108 void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg) 2109 { 2110 ops_reader_info_t *rinfo=malloc(sizeof *rinfo); 2111 2112 *rinfo=pinfo->rinfo; 2113 pinfo->rinfo.next=rinfo; 2114 ops_reader_set(pinfo,reader,arg); 2115 } 2116 2117 void *ops_reader_get_arg(ops_reader_info_t *rinfo) 2118 { return rinfo->arg; } 2119 2120 ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo) 2121 { return pinfo->errors; } 2019 2122 2020 2123 /* vim:set textwidth=120: */ openpgpsdk/trunk/src/util.c
r312 r320 79 79 } 80 80 81 /** Arguments for reader_fd 82 */ 83 typedef struct 84 { 85 int fd; /*!< file descriptor */ 86 } reader_fd_arg_t; 87 81 88 /** 82 89 * \ingroup Parse … … 103 110 * \todo change arg_ to typesafe? 104 111 */ 105 ops_reader_ret_t ops_reader_fd(unsigned char *dest,unsigned *plength, 106 ops_reader_flags_t flags, 107 ops_parse_info_t *parse_info) 112 static ops_reader_ret_t reader_fd(unsigned char *dest,unsigned *plength, 113 ops_reader_flags_t flags, 114 ops_error_t **errors, 115 ops_reader_info_t *rinfo, 116 ops_parse_cb_info_t *cbinfo) 108 117 { 109 ops_reader_fd_arg_t *arg=parse_info->reader_arg;118 reader_fd_arg_t *arg=ops_reader_get_arg(rinfo); 110 119 int n=read(arg->fd,dest,*plength); 120 121 OPS_USED(cbinfo); 111 122 112 123 if(n == 0) … … 115 126 if(n == -1) 116 127 { 117 ops_system_error_1(&parse_info->errors,OPS_E_R_READ_FAILED,"read",128 OPS_SYSTEM_ERROR_1(errors,OPS_E_R_READ_FAILED,"read", 118 129 "file descriptor %d",arg->fd); 119 130 return OPS_R_ERROR; … … 129 140 else 130 141 { 131 ops_error_1(&parse_info->errors,OPS_E_R_EARLY_EOF, 132 "file descriptor %d",arg->fd); 142 OPS_ERROR_1(errors,OPS_E_R_EARLY_EOF,"file descriptor %d",arg->fd); 133 143 return OPS_R_EARLY_EOF; 134 144 } … … 142 152 } 143 153 154 void ops_reader_set_fd(ops_parse_info_t *pinfo,int fd) 155 { 156 reader_fd_arg_t *arg=malloc(sizeof *arg); 157 158 arg->fd=fd; 159 ops_reader_set(pinfo,reader_fd,arg); 160 } 161 144 162 void *ops_mallocz(size_t n) 145 163 { openpgpsdk/trunk/src/validate.c
r308 r320 7 7 #include <string.h> 8 8 9 /* XXX: because we might well use this reader with different callbacks10 it would make sense to split the arguments for callbacks, one for the reader11 and one for the callback */12 9 typedef struct 13 10 { … … 28 25 static ops_reader_ret_t key_data_reader(unsigned char *dest,unsigned *plength, 29 26 ops_reader_flags_t flags, 30 ops_parse_info_t *parse_info) 27 ops_error_t **errors, 28 ops_reader_info_t *rinfo, 29 ops_parse_cb_info_t *cbinfo) 31 30 { 32 validate_reader_arg_t *arg= parse_info->reader_arg;31 validate_reader_arg_t *arg=ops_reader_get_arg(rinfo); 33 32 34 33 OPS_USED(flags); 34 OPS_USED(errors); 35 OPS_USED(cbinfo); 35 36 if(arg->offset == arg->key->packets[arg->packet].length) 36 37 { … … 55 56 */ 56 57 57 static ops_parse_c allback_return_t58 validate_cb(const ops_parser_content_t *content_, void *arg_)58 static ops_parse_cb_return_t 59 validate_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 59 60 { 60 61 const ops_parser_content_union_t *content=&content_->content; 61 validate_cb_arg_t *arg= arg_;62 validate_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); 62 63 const ops_key_data_t *signer; 63 64 ops_boolean_t valid; … … 137 138 const ops_keyring_t *keyring) 138 139 { 139 ops_parse_info_t parse_info;140 ops_parse_info_t *pinfo; 140 141 validate_cb_arg_t carg; 141 142 validate_reader_arg_t rarg; … … 144 145 memset(&carg,'\0',sizeof carg); 145 146 146 ops_parse_info_init(&parse_info);147 pinfo=ops_parse_info_new(); 147 148 // ops_parse_options(&opt,OPS_PTAG_CT_SIGNATURE,OPS_PARSE_PARSED); 148 parse_info.cb=validate_cb;149 parse_info.reader=key_data_reader;150 149 151 150 rarg.key=key; … … 156 155 carg.rarg=&rarg; 157 156 158 parse_info.cb_arg=&carg;159 parse_info.reader_arg=&rarg;157 ops_parse_cb_set(pinfo,validate_cb,&carg); 158 ops_reader_set(pinfo,key_data_reader,&rarg); 160 159 161 ops_parse( &parse_info);160 ops_parse(pinfo); 162 161 163 162 ops_public_key_free(&carg.pkey);
