Changeset 22
- Timestamp:
- 01/16/05 21:14:46
- Files:
-
- openpgpsdk/trunk/src/packet-dump.c (modified) (3 diffs)
- openpgpsdk/trunk/src/packet-parse.c (modified) (8 diffs)
- openpgpsdk/trunk/src/packet-parse.h (modified) (1 diff)
- openpgpsdk/trunk/src/packet.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
openpgpsdk/trunk/src/packet-dump.c
r21 r22 5 5 #include <assert.h> 6 6 #include <stdlib.h> 7 8 static void hexdump(const unsigned char *src,size_t length) 9 { 10 while(length--) 11 printf("%02X",*src++); 12 } 7 13 8 14 static ops_packet_reader_ret_t reader(unsigned char *dest,unsigned length) … … 15 21 if(n != length) 16 22 return OPS_PR_EARLY_EOF; 17 23 #if 0 24 printf("[read 0x%x: ",length); 25 hexdump(dest,length); 26 putchar(']'); 27 #endif 18 28 return OPS_PR_OK; 19 }20 21 static void hexdump(const char *src,size_t length)22 {23 while(length--)24 printf("%02X",*src++);25 29 } 26 30 … … 120 124 int main(int argc,char **argv) 121 125 { 122 ops_parse_packet(reader,callback); 126 ops_parse_packet_options_t opt; 127 128 ops_parse_packet_options_init(&opt); 129 ops_parse_packet(reader,callback,&opt); 123 130 124 131 return 0; openpgpsdk/trunk/src/packet-parse.c
r21 r22 12 12 #define ERR1(fmt,x) do { format_error(&content,(fmt),(x)); E; } while(0) 13 13 14 /* XXX: replace ops_ptag_t with something more appropriate for limiting 15 reads */ 16 14 17 /* Note that this makes the parser non-reentrant, in a limited way */ 15 18 /* It is the caller's responsibility to avoid overflow in the buffer */ … … 60 63 ptag->length_read+=length; 61 64 65 return 1; 66 } 67 68 static int limited_skip(unsigned length,ops_ptag_t *ptag, 69 ops_packet_reader_t *reader, 70 ops_packet_parse_callback_t *cb) 71 { 72 unsigned char buf[8192]; 73 74 while(length) 75 { 76 int n=length%8192; 77 if(!limited_read(buf,n,ptag,reader,cb)) 78 return 0; 79 length-=n; 80 } 62 81 return 1; 63 82 } … … 116 135 *pbn=BN_bin2bn(buf,length,NULL); 117 136 return 1; 137 } 138 139 static int limited_read_new_length(unsigned *length,ops_ptag_t *ptag, 140 ops_packet_reader_t *reader, 141 ops_packet_parse_callback_t *cb) 142 { 143 unsigned char c[1]; 144 145 if(!limited_read(c,1,ptag,reader,cb)) 146 return 0; 147 if(c[0] < 192) 148 { 149 *length=c[0]; 150 return 1; 151 } 152 if(c[0] < 255) 153 { 154 unsigned t=(c[0]-192) << 8; 155 156 if(!limited_read(c,1,ptag,reader,cb)) 157 return 0; 158 *length=t+c[1]+192; 159 return 1; 160 } 161 return limited_read_scalar(length,4,ptag,reader,cb); 118 162 } 119 163 … … 253 297 } 254 298 299 static int parse_one_signature_subpacket(ops_ptag_t *ptag, 300 ops_packet_reader_t *reader, 301 ops_packet_parse_callback_t *cb, 302 ops_parse_packet_options_t *opt) 303 { 304 ops_ptag_t subptag; 305 char c[1]; 306 ops_parser_content_t content; 307 unsigned t8,t7; 308 309 memset(&subptag,'\0',sizeof subptag); 310 if(!limited_read_new_length(&subptag.length,ptag,reader,cb)) 311 return 0; 312 313 if(!limited_read(c,1,&subptag,reader,cb)) 314 return 0; 315 316 t8=(c[0]&0x7f)/8; 317 t7=1 << (c[0]&7); 318 319 content.critical=c[0] >> 7; 320 content.tag=OPS_PTAG_SIGNATURE_SUBPACKET_BASE+(c[0]&0x7f); 321 if(opt->ss_raw[t8]&t7) 322 { 323 C.ss_raw.tag=content.tag; 324 C.ss_raw.raw=malloc(subptag.length-1); 325 if(!limited_read(C.ss_raw.raw,subptag.length-1,ptag,reader,cb)) 326 return 0; 327 ptag->length_read+=subptag.length; 328 CB(OPS_PTAG_RAW_SS,&content); 329 return 1; 330 } 331 if(!(opt->ss_parsed[t8]&t7)) 332 { 333 if(content.critical) 334 ERR1("Critical signature subpacket ignored (%d)",c[0]&0x7f); 335 if(!limited_skip(subptag.length-1,&subptag,reader,cb)) 336 return 0; 337 printf("skipped %d length %d\n",c[0]&0x7f,subptag.length); 338 ptag->length_read+=subptag.length; 339 return 1; 340 } 341 342 switch(content.tag) 343 { 344 case OPS_PTAG_SS_TRUST: 345 if(!limited_read(&C.ss_trust.level,1,&subptag,reader,cb) 346 || !limited_read(&C.ss_trust.level,1,&subptag,reader,cb)) 347 return 0; 348 break; 349 350 default: 351 ERR1("Unknown signature subpacket type (%d)",c[0]&0x7f); 352 } 353 354 ptag->length_read+=subptag.length; 355 cb(&content); 356 357 return 1; 358 } 359 360 static int parse_signature_subpackets(ops_ptag_t *ptag, 361 ops_packet_reader_t *reader, 362 ops_packet_parse_callback_t *cb, 363 ops_parse_packet_options_t *opt) 364 { 365 ops_ptag_t subptag; 366 367 memset(&subptag,'\0',sizeof subptag); 368 if(!limited_read_scalar(&subptag.length,2,ptag,reader,cb)) 369 return 0; 370 371 while(subptag.length_read < subptag.length) 372 if(!parse_one_signature_subpacket(&subptag,reader,cb,opt)) 373 { 374 ptag->length_read+=subptag.length_read; 375 return 0; 376 } 377 378 assert(subptag.length_read == subptag.length); 379 ptag->length_read+=subptag.length_read; 380 381 return 1; 382 } 383 255 384 static int parse_v4_signature(ops_ptag_t *ptag,ops_packet_reader_t *reader, 256 ops_packet_parse_callback_t *cb) 257 { 258 assert(0); 385 ops_packet_parse_callback_t *cb, 386 ops_parse_packet_options_t *opt) 387 { 388 unsigned char c[1]; 389 ops_parser_content_t content; 390 391 C.signature.version=OPS_SIG_V4; 392 393 if(!limited_read(c,1,ptag,reader,cb)) 394 return 0; 395 C.signature.type=c[0]; 396 /* XXX: check signature type */ 397 398 if(!limited_read(c,1,ptag,reader,cb)) 399 return 0; 400 C.signature.key_algorithm=c[0]; 401 /* XXX: check algorithm */ 402 403 if(!limited_read(c,1,ptag,reader,cb)) 404 return 0; 405 C.signature.hash_algorithm=c[0]; 406 /* XXX: check algorithm */ 407 408 if(!parse_signature_subpackets(ptag,reader,cb,opt)) 409 return 0; 410 411 if(!parse_signature_subpackets(ptag,reader,cb,opt)) 412 return 0; 413 414 415 416 if(!limited_read(C.signature.hash2,2,ptag,reader,cb)) 417 return 0; 418 419 switch(C.signature.key_algorithm) 420 { 421 case OPS_PKA_RSA: 422 if(!limited_read_mpi(&C.signature.signature.rsa.sig,ptag,reader,cb)) 423 return 0; 424 break; 425 426 case OPS_PKA_DSA: 427 if(!limited_read_mpi(&C.signature.signature.dsa.r,ptag,reader,cb) 428 || !limited_read_mpi(&C.signature.signature.dsa.s,ptag,reader,cb)) 429 return 0; 430 break; 431 432 default: 433 ERR1("Bad signature key algorithm (%d)",C.signature.key_algorithm); 434 } 435 436 if(ptag->length_read != ptag->length) 437 ERR1("Unconsumed data (%d)", ptag->length-ptag->length_read); 438 439 CB(OPS_PTAG_CT_SIGNATURE,&content); 259 440 260 441 return 1; … … 262 443 263 444 static int parse_signature(ops_ptag_t *ptag,ops_packet_reader_t *reader, 264 ops_packet_parse_callback_t *cb) 445 ops_packet_parse_callback_t *cb, 446 ops_parse_packet_options_t *opt) 265 447 { 266 448 unsigned char c[1]; … … 274 456 return parse_v3_signature(ptag,reader,cb); 275 457 else if(c[0] == 4) 276 return parse_v4_signature(ptag,reader,cb );458 return parse_v4_signature(ptag,reader,cb,opt); 277 459 ERR1("Bad signature version (%d)",c[0]); 278 460 } 279 461 280 462 static int ops_parse_one_packet(ops_packet_reader_t *reader, 281 ops_packet_parse_callback_t *cb) 463 ops_packet_parse_callback_t *cb, 464 ops_parse_packet_options_t *opt) 282 465 { 283 466 char ptag[1]; … … 336 519 { 337 520 case OPS_PTAG_CT_SIGNATURE: 338 r=parse_signature(&C.ptag,reader,cb );521 r=parse_signature(&C.ptag,reader,cb,opt); 339 522 break; 340 523 … … 357 540 358 541 void ops_parse_packet(ops_packet_reader_t *reader, 359 ops_packet_parse_callback_t *cb) 360 { 361 while(ops_parse_one_packet(reader,cb)) 542 ops_packet_parse_callback_t *cb, 543 ops_parse_packet_options_t *opt) 544 { 545 while(ops_parse_one_packet(reader,cb,opt)) 362 546 ; 363 547 } 548 549 void ops_parse_packet_options(ops_parse_packet_options_t *opt, 550 ops_content_tag_t tag, 551 ops_parse_type_t type) 552 { 553 int t8,t7; 554 555 assert(tag >= OPS_PTAG_SIGNATURE_SUBPACKET_BASE 556 && tag <= OPS_PTAG_SIGNATURE_SUBPACKET_BASE+255); 557 t8=(tag-OPS_PTAG_SIGNATURE_SUBPACKET_BASE)/8; 558 t7=1 << ((tag-OPS_PTAG_SIGNATURE_SUBPACKET_BASE)&7); 559 switch(type) 560 { 561 case OPS_PARSE_RAW: 562 opt->ss_raw[t8] |= t7; 563 opt->ss_parsed[t8] &= ~t7; 564 break; 565 566 case OPS_PARSE_PARSED: 567 opt->ss_raw[t8] &= ~t7; 568 opt->ss_parsed[t8] |= t7; 569 break; 570 571 case OPS_PARSE_IGNORE: 572 opt->ss_raw[t8] &= ~t7; 573 opt->ss_parsed[t8] &= ~t7; 574 break; 575 } 576 } 577 578 openpgpsdk/trunk/src/packet-parse.h
r21 r22 10 10 unsigned length); 11 11 12 typedef struct 13 { 14 unsigned char ss_raw[256/8]; 15 unsigned char ss_parsed[256/8]; 16 } ops_parse_packet_options_t; 17 12 18 void ops_parse_packet(ops_packet_reader_t *reader, 13 ops_packet_parse_callback_t *cb); 19 ops_packet_parse_callback_t *cb, 20 ops_parse_packet_options_t *opt); 21 22 typedef enum 23 { 24 OPS_PARSE_RAW, 25 OPS_PARSE_PARSED, 26 OPS_PARSE_IGNORE 27 } ops_parse_type_t; 28 29 #define ops_parse_packet_options_init(opt) memset(opt,'\0',sizeof *opt) 30 31 void ops_parse_packet_options(ops_parse_packet_options_t *opt, 32 ops_content_tag_t tag, 33 ops_parse_type_t type); 34 openpgpsdk/trunk/src/packet.h
r21 r22 57 57 OPS_PARSER_ERROR =0x100, 58 58 OPS_PARSER_PTAG =0x101, 59 OPS_PTAG_RAW_SS =0x102, 60 61 /* signature subpackets (0x200-2ff) (type+0x200) */ 62 /* only those we can parse are listed here */ 63 OPS_PTAG_SIGNATURE_SUBPACKET_BASE =0x200, 64 OPS_PTAG_SS_CREATION_TIME =0x200+2, 65 OPS_PTAG_SS_EXPIRATION_TIME =0x200+3, 66 OPS_PTAG_SS_TRUST =0x200+5, 59 67 } ops_content_tag_t; 60 68 … … 186 194 } ops_signature_t; 187 195 196 typedef struct 197 { 198 ops_content_tag_t tag; 199 unsigned char *raw; 200 } ops_ss_raw_t; 201 202 typedef struct 203 { 204 unsigned char level; 205 unsigned char amount; 206 } ops_ss_trust_t; 207 188 208 typedef union 189 209 { … … 193 213 ops_user_id_t user_id; 194 214 ops_signature_t signature; 215 ops_ss_raw_t ss_raw; 216 ops_ss_trust_t ss_trust; 195 217 } ops_parser_content_union_t; 196 218 … … 198 220 { 199 221 ops_content_tag_t tag; 222 unsigned char critical; /* for signature subpackets */ 200 223 ops_parser_content_union_t content; 201 224 } ops_parser_content_t;
