Changeset 22

Show
Ignore:
Timestamp:
01/16/05 21:14:46
Author:
ben
Message:

signature subpacket sketch.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openpgpsdk/trunk/src/packet-dump.c

    r21 r22  
    55#include <assert.h> 
    66#include <stdlib.h> 
     7 
     8static void hexdump(const unsigned char *src,size_t length) 
     9    { 
     10    while(length--) 
     11        printf("%02X",*src++); 
     12    } 
    713 
    814static ops_packet_reader_ret_t reader(unsigned char *dest,unsigned length) 
     
    1521    if(n != length) 
    1622        return OPS_PR_EARLY_EOF; 
    17  
     23#if 0 
     24    printf("[read 0x%x: ",length); 
     25    hexdump(dest,length); 
     26    putchar(']'); 
     27#endif 
    1828    return OPS_PR_OK; 
    19     } 
    20  
    21 static void hexdump(const char *src,size_t length) 
    22     { 
    23     while(length--) 
    24         printf("%02X",*src++); 
    2529    } 
    2630 
     
    120124int main(int argc,char **argv) 
    121125    { 
    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); 
    123130 
    124131    return 0; 
  • openpgpsdk/trunk/src/packet-parse.c

    r21 r22  
    1212#define ERR1(fmt,x)     do { format_error(&content,(fmt),(x)); E; } while(0) 
    1313 
     14/* XXX: replace ops_ptag_t with something more appropriate for limiting 
     15   reads */ 
     16 
    1417/* Note that this makes the parser non-reentrant, in a limited way */ 
    1518/* It is the caller's responsibility to avoid overflow in the buffer */ 
     
    6063    ptag->length_read+=length; 
    6164 
     65    return 1; 
     66    } 
     67 
     68static 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        } 
    6281    return 1; 
    6382    } 
     
    116135    *pbn=BN_bin2bn(buf,length,NULL); 
    117136    return 1; 
     137    } 
     138 
     139static 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); 
    118162    } 
    119163 
     
    253297    } 
    254298 
     299static 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 
     360static 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 
    255384static 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); 
    259440 
    260441    return 1; 
     
    262443 
    263444static 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) 
    265447    { 
    266448    unsigned char c[1]; 
     
    274456        return parse_v3_signature(ptag,reader,cb); 
    275457    else if(c[0] == 4) 
    276         return parse_v4_signature(ptag,reader,cb); 
     458        return parse_v4_signature(ptag,reader,cb,opt); 
    277459    ERR1("Bad signature version (%d)",c[0]); 
    278460    } 
    279461 
    280462static 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) 
    282465    { 
    283466    char ptag[1]; 
     
    336519        { 
    337520    case OPS_PTAG_CT_SIGNATURE: 
    338         r=parse_signature(&C.ptag,reader,cb); 
     521        r=parse_signature(&C.ptag,reader,cb,opt); 
    339522        break; 
    340523 
     
    357540 
    358541void 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)) 
    362546        ; 
    363547    } 
     548 
     549void 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  
    1010                                                  unsigned length); 
    1111 
     12typedef struct 
     13    { 
     14    unsigned char ss_raw[256/8]; 
     15    unsigned char ss_parsed[256/8]; 
     16    } ops_parse_packet_options_t; 
     17 
    1218void 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 
     22typedef 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 
     31void 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  
    5757    OPS_PARSER_ERROR                    =0x100, 
    5858    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, 
    5967    } ops_content_tag_t; 
    6068 
     
    186194    } ops_signature_t; 
    187195 
     196typedef struct 
     197    { 
     198    ops_content_tag_t           tag; 
     199    unsigned char               *raw; 
     200    } ops_ss_raw_t; 
     201 
     202typedef struct 
     203    { 
     204    unsigned char               level; 
     205    unsigned char               amount; 
     206    } ops_ss_trust_t; 
     207 
    188208typedef union 
    189209    { 
     
    193213    ops_user_id_t               user_id; 
    194214    ops_signature_t             signature; 
     215    ops_ss_raw_t                ss_raw; 
     216    ops_ss_trust_t              ss_trust; 
    195217    } ops_parser_content_union_t; 
    196218 
     
    198220    { 
    199221    ops_content_tag_t           tag; 
     222    unsigned char               critical; /* for signature subpackets */ 
    200223    ops_parser_content_union_t  content; 
    201224    } ops_parser_content_t;