Changeset 235

Show
Ignore:
Timestamp:
10/13/05 15:32:07
Author:
ben
Message:

Check signed cleartext. Also rename a prefixless function.

Files:

Legend:

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

    r233 r235  
    77#include "ops_errors.h" 
    88#include "armour.h" 
     9#include "crypto.h" 
    910 
    1011#include <unistd.h> 
     
    207208        print_indent(); 
    208209    printf("<<<<< %s <<<<<\n",name); 
     210    } 
     211 
     212static void print_headers(const ops_headers_t *headers) 
     213    { 
     214    int n; 
     215 
     216    for(n=0 ; n < headers->nheaders ; ++n) 
     217        printf("%s=%s\n",headers->headers[n].key,headers->headers[n].value); 
    209218    } 
    210219 
     
    771780    case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 
    772781        print_tagname("SIGNED CLEARTEXT HEADER"); 
     782        print_headers(&content->signed_cleartext_header.headers); 
    773783        break; 
    774784 
     
    777787        print_block("signed cleartext",content->signed_cleartext_body.data, 
    778788                    content->signed_cleartext_body.length); 
     789        break; 
     790 
     791    case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 
     792        print_tagname("SIGNED CLEARTEXT TRAILER"); 
     793        printf("hash algorithm: %d\n", 
     794               content->signed_cleartext_trailer.hash->algorithm); 
     795        printf("\n"); 
    779796        break; 
    780797 
  • openpgpsdk/trunk/examples/verify2.c

    r233 r235  
    55#include "keyring.h" 
    66#include "validate.h" 
     7#include "armour.h" 
     8#include "crypto.h" 
     9#include "signature.h" 
    710#include <unistd.h> 
    811#include <string.h> 
     
    1720    } 
    1821 
     22static ops_keyring_t keyring; 
     23static unsigned length; 
     24static unsigned char *signed_data; 
     25static ops_hash_t *signed_hash; 
     26 
     27// FIXME: should this be a part of the library? 
     28static ops_parse_callback_return_t 
     29callback(const ops_parser_content_t *content_,void *arg_) 
     30    { 
     31    const ops_parser_content_union_t *content=&content_->content; 
     32    const ops_key_data_t *signer; 
     33 
     34    switch(content_->tag) 
     35        { 
     36    case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 
     37        free(signed_data); 
     38        signed_data=NULL; 
     39        length=0; 
     40        break; 
     41 
     42    case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: 
     43        signed_data=realloc(signed_data, 
     44                            length+content->signed_cleartext_body.length); 
     45        memcpy(signed_data+length,content->signed_cleartext_body.data, 
     46               content->signed_cleartext_body.length); 
     47        length+=content->signed_cleartext_body.length; 
     48        break; 
     49 
     50    case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 
     51        signed_hash=content->signed_cleartext_trailer.hash; 
     52        return OPS_KEEP_MEMORY; 
     53 
     54    case OPS_PTAG_CT_SIGNATURE: 
     55        signer=ops_keyring_find_key_by_id(&keyring, 
     56                                          content->signature.signer_id); 
     57        if(!signer) 
     58            { 
     59            fprintf(stderr,"SIGNER UNKNOWN!!!\n"); 
     60            exit(2); 
     61            } 
     62 
     63        if(ops_check_hash_signature(signed_hash,&content->signature, 
     64                                    ops_get_public_key_from_data(signer))) 
     65            { 
     66            puts("Good signature...\n"); 
     67            fputs(signed_data,stdout); 
     68            free(signed_data); 
     69            length=0; 
     70            } 
     71        else 
     72            { 
     73            fprintf(stderr,"BAD SIGNATURE!!!\n"); 
     74            exit(1); 
     75            } 
     76        break; 
     77 
     78    case OPS_PARSER_ERROR: 
     79        printf("parse error: %s\n",content->error.error); 
     80        exit(1); 
     81        break; 
     82 
     83    case OPS_PTAG_CT_ARMOUR_HEADER: 
     84        if(!strcmp(content->armour_header.type,"BEGIN PGP SIGNATURE")) 
     85            break; 
     86        fprintf(stderr,"unexpected armour header: %s\n", 
     87                content->armour_header.type); 
     88        exit(3); 
     89        break; 
     90 
     91    case OPS_PTAG_CT_ARMOUR_TRAILER: 
     92        if(!strcmp(content->armour_trailer.type,"END PGP SIGNATURE")) 
     93            break; 
     94        fprintf(stderr,"unexpected armour trailer: %s\n", 
     95                content->armour_header.type); 
     96        exit(4); 
     97        break; 
     98 
     99    case OPS_PARSER_PTAG: 
     100        // just ignore these 
     101        break; 
     102 
     103    default: 
     104        fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag, 
     105                content_->tag); 
     106        exit(1); 
     107        } 
     108 
     109    return OPS_RELEASE_MEMORY; 
     110    } 
     111 
    19112int main(int argc,char **argv) 
    20113    { 
    21114    ops_parse_options_t opt; 
    22     ops_keyring_t keyring; 
    23115    ops_reader_fd_arg_t arg; 
    24116    const char *keyfile; 
     
    40132            } 
    41133 
    42     keyfile=argv[1]; 
    43     verify=argv[2]; 
     134    keyfile=argv[optind++]; 
     135    verify=argv[optind++]; 
    44136 
    45137    ops_init(); 
     
    60152    ops_parse_and_accumulate(&keyring,&opt); 
    61153 
     154    close(arg.fd); 
     155 
    62156    ops_dump_keyring(&keyring); 
    63157 
     158    ops_parse_options_init(&opt); 
     159 
     160    arg.fd=open(verify,O_RDONLY); 
     161    if(arg.fd < 0) 
     162        { 
     163        perror(verify); 
     164        exit(2); 
     165        } 
     166 
     167    opt.reader_arg=&arg; 
     168    opt.reader=ops_reader_fd; 
     169 
     170    opt.cb=callback; 
     171 
     172    if(armour) 
     173        ops_push_dearmour(&opt); 
     174 
     175    ops_parse(&opt); 
     176 
     177    free(signed_data); 
    64178    ops_keyring_free(&keyring); 
    65  
    66179    ops_finish(); 
    67180 
  • openpgpsdk/trunk/include/crypto.h

    r140 r235  
    88#define OPS_CRYPTO_H 
    99 
    10 #define OPS_MAX_HASH    20 
     10#define OPS_MAX_HASH    64 
    1111 
    1212typedef struct _ops_hash_t ops_hash_t; 
     
    1919struct _ops_hash_t 
    2020    { 
     21    ops_hash_algorithm_t algorithm; 
    2122    ops_hash_init_t *init; 
    2223    ops_hash_add_t *add; 
     
    2930void ops_hash_md5(ops_hash_t *hash); 
    3031void ops_hash_sha1(ops_hash_t *hash); 
     32void ops_hash_any(ops_hash_t *hash,ops_hash_algorithm_t alg); 
     33ops_hash_algorithm_t ops_hash_algorithm_from_text(const char *hash); 
     34unsigned ops_hash_size(ops_hash_algorithm_t alg); 
    3135 
    32 void hash_add_int(ops_hash_t *hash,unsigned n,unsigned length); 
     36void ops_hash_add_int(ops_hash_t *hash,unsigned n,unsigned length); 
    3337 
    3438ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length, 
  • openpgpsdk/trunk/include/keyring.h

    r183 r235  
    2626void ops_keyring_free(ops_keyring_t *keyring); 
    2727void ops_dump_keyring(const ops_keyring_t *keyring); 
     28const ops_public_key_t * 
     29ops_get_public_key_from_data(const ops_key_data_t *data); 
    2830 
    2931#endif 
  • openpgpsdk/trunk/include/packet.h

    r228 r235  
    195195    OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER =0x300+6, 
    196196    OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY   =0x300+7, 
    197     OPS_PTAG_CT_UNARMOURED_TEXT         =0x300+8, 
     197    OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER=0x300+8, 
     198    OPS_PTAG_CT_UNARMOURED_TEXT         =0x300+9, 
    198199    }; 
    199200 
     
    433434typedef enum 
    434435    { 
     436    OPS_HASH_UNKNOWN    =-1,    /*!< used to indicate errors */ 
    435437    OPS_HASH_MD5        = 1,    /*!< MD5 */ 
    436438    OPS_HASH_SHA1       = 2,    /*!< SHA-1 */ 
     
    673675typedef struct 
    674676    { 
    675     const char *key; 
    676     const char *value; 
     677    char *key; 
     678    char *value; 
    677679    } ops_armoured_header_value_t; 
     680 
     681typedef struct 
     682    { 
     683    ops_armoured_header_value_t *headers; 
     684    unsigned nheaders; 
     685    } ops_headers_t; 
    678686 
    679687typedef struct 
     
    689697typedef struct 
    690698    { 
     699    ops_headers_t headers; 
    691700    } ops_signed_cleartext_header_t; 
    692701 
     
    696705    unsigned char               data[8192]; 
    697706    } ops_signed_cleartext_body_t; 
     707 
     708typedef struct 
     709    { 
     710    struct _ops_hash_t          *hash;  /*!< This will not have been finalised, but will have seen all the cleartext data in canonical form */ 
     711    } ops_signed_cleartext_trailer_t; 
    698712 
    699713typedef struct 
     
    744758    ops_signed_cleartext_header_t signed_cleartext_header; 
    745759    ops_signed_cleartext_body_t signed_cleartext_body; 
     760    ops_signed_cleartext_trailer_t signed_cleartext_trailer; 
    746761    ops_unarmoured_text_t       unarmoured_text; 
    747762    } ops_parser_content_union_t; 
  • openpgpsdk/trunk/include/signature.h

    r142 r235  
    1818                           const ops_public_key_t *signer, 
    1919                           const unsigned char *raw_packet); 
     20ops_boolean_t 
     21ops_check_hash_signature(ops_hash_t *hash, 
     22                         const ops_signature_t *sig, 
     23                         const ops_public_key_t *signer); 
    2024void ops_signature_start(ops_create_signature_t *sig, 
    2125                         const ops_public_key_t *key, 
  • openpgpsdk/trunk/src/armour.c

    r234 r235  
    11#include "armour.h" 
    22#include "util.h" 
     3#include "crypto.h" 
    34 
    45#include <string.h> 
     
    3435    unsigned npushed_back; 
    3536    // armoured block headers 
    36     ops_armoured_header_value_t **headers; 
    37     unsigned nheaders; 
     37    ops_headers_t headers; 
    3838    } dearmour_arg_t; 
    3939 
     
    121121    } 
    122122 
     123const char *ops_find_header(ops_headers_t *headers,const char *key) 
     124    { 
     125    int n; 
     126 
     127    for(n=0 ; n < headers->nheaders ; ++n) 
     128        if(!strcmp(headers->headers[n].key,key)) 
     129            return headers->headers[n].value; 
     130    return NULL; 
     131    } 
     132 
     133void ops_dup_headers(ops_headers_t *dest,const ops_headers_t *src) 
     134    { 
     135    int n; 
     136 
     137    dest->headers=malloc(src->nheaders*sizeof *dest->headers); 
     138    dest->nheaders=src->nheaders; 
     139 
     140    for(n=0 ; n < src->nheaders ; ++n) 
     141        { 
     142        dest->headers[n].key=strdup(src->headers[n].key); 
     143        dest->headers[n].value=strdup(src->headers[n].value); 
     144        } 
     145    } 
     146 
     147/* Note that this skips CRs so implementations always see just 
     148   straight LFs as line terminators */ 
    123149static ops_reader_ret_t process_dash_escaped(dearmour_arg_t *arg) 
    124150    { 
    125151    ops_parser_content_t content; 
    126     ops_signed_cleartext_body_t *body=&content.content.signed_cleartext_body; 
     152    ops_parser_content_t content2; 
     153    ops_signed_cleartext_body_t *body=&content.content.signed_cleartext_body; 
     154    ops_signed_cleartext_trailer_t *trailer 
     155        =&content2.content.signed_cleartext_trailer; 
     156    const char *hashstr; 
     157    ops_hash_t *hash; 
     158 
     159    hash=malloc(sizeof *hash); 
     160    hashstr=ops_find_header(&arg->headers,"Hash"); 
     161    if(hashstr) 
     162        { 
     163        ops_hash_algorithm_t alg; 
     164 
     165        alg=ops_hash_algorithm_from_text(hashstr); 
     166        if(alg == OPS_HASH_UNKNOWN) 
     167            ERR("Unknown hash algorithm"); 
     168        ops_hash_any(hash,alg); 
     169        } 
     170    else 
     171        ops_hash_md5(hash); 
     172 
     173    hash->init(hash); 
    127174 
    128175    body->length=0; 
     
    132179        unsigned count; 
    133180 
    134         if((c=read_char(arg,ops_false)) < 0) 
     181        if((c=read_char(arg,ops_true)) < 0) 
    135182            return OPS_R_EARLY_EOF; 
    136183        if(arg->prev_nl && c == '-') 
     
    157204                return OPS_R_EARLY_EOF; 
    158205            } 
     206        if(c == '\n' && body->length) 
     207            { 
     208            assert(memchr(body->data+1,'\n',body->length-1) == NULL); 
     209            if(body->data[0] == '\n') 
     210                hash->add(hash,"\r",1); 
     211            hash->add(hash,body->data,body->length); 
     212            CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 
     213            body->length=0; 
     214            } 
     215                 
    159216        body->data[body->length++]=c; 
    160217        if(body->length == sizeof body->data) 
     
    165222        } 
    166223 
    167     if(body->length) 
    168         CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 
     224    assert(body->data[0] == '\n'); 
     225    assert(body->length == 1); 
     226    // and we don't send that one character, because its part of the trailer. 
     227    //    if(body->length) 
     228    //  CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 
     229 
     230    trailer->hash=hash; 
     231    CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER,&content2); 
    169232 
    170233    return OPS_R_OK; 
     
    174237                       *value) 
    175238    { 
    176     ops_armoured_header_value_t *header; 
    177  
    178     header=malloc(sizeof *header); 
    179     header->key=strdup(key); 
    180     header->value=strdup(value); 
    181  
    182     arg->headers=realloc(arg->headers,(arg->nheaders+1)*sizeof *arg->headers); 
    183     arg->headers[arg->nheaders++]=header; 
     239    arg->headers.headers=realloc(arg->headers.headers, 
     240                                 (arg->headers.nheaders+1) 
     241                                 *sizeof *arg->headers.headers); 
     242    arg->headers.headers[arg->headers.nheaders].key=strdup(key); 
     243    arg->headers.headers[arg->headers.nheaders].value=strdup(value); 
     244    ++arg->headers.nheaders; 
    184245    } 
    185246 
     
    436497        int c; 
    437498 
     499        flush(arg); 
    438500        switch(arg->state) 
    439501            { 
     
    501563                { 
    502564                ops_reader_ret_t ret; 
     565 
     566                ops_dup_headers(&content.content.signed_cleartext_header.headers,&arg->headers); 
    503567                CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER,&content); 
     568 
    504569                ret=process_dash_escaped(arg); 
    505570                if(ret != OPS_R_OK) 
  • openpgpsdk/trunk/src/fingerprint.c

    r177 r235  
    5656        sha1.init(&sha1); 
    5757 
    58         hash_add_int(&sha1,0x99,1); 
    59         hash_add_int(&sha1,mem.length,2); 
     58        ops_hash_add_int(&sha1,0x99,1); 
     59        ops_hash_add_int(&sha1,mem.length,2); 
    6060        sha1.add(&sha1,mem.buf,mem.length); 
    6161        sha1.finish(&sha1,fp->fingerprint); 
  • openpgpsdk/trunk/src/hash.c

    r135 r235  
    33 
    44#include "crypto.h" 
     5#include <assert.h> 
    56 
    6 void hash_add_int(ops_hash_t *hash,unsigned n,unsigned length) 
     7void ops_hash_add_int(ops_hash_t *hash,unsigned n,unsigned length) 
    78    { 
    89    while(length--) 
     
    1415        } 
    1516    } 
     17 
     18void ops_hash_any(ops_hash_t *hash,ops_hash_algorithm_t alg) 
     19    { 
     20    switch(alg) 
     21        { 
     22    case OPS_HASH_MD5: 
     23        ops_hash_md5(hash); 
     24        break; 
     25 
     26    case OPS_HASH_SHA1: 
     27        ops_hash_sha1(hash); 
     28        break; 
     29 
     30    default: 
     31        assert(0); 
     32        } 
     33    } 
     34 
     35unsigned ops_hash_size(ops_hash_algorithm_t alg) 
     36    { 
     37    switch(alg) 
     38        { 
     39    case OPS_HASH_MD5: 
     40        return 16; 
     41 
     42    case OPS_HASH_SHA1: 
     43        return 20; 
     44 
     45    default: 
     46        assert(0); 
     47        } 
     48 
     49    return 0; 
     50    } 
     51 
     52ops_hash_algorithm_t ops_hash_algorithm_from_text(const char *hash) 
     53    { 
     54    if(!strcmp(hash,"SHA1")) 
     55        return OPS_HASH_SHA1; 
     56    else if(!strcmp(hash,"MD5")) 
     57        return OPS_HASH_MD5; 
     58 
     59    return OPS_HASH_UNKNOWN; 
     60    } 
     61 
  • openpgpsdk/trunk/src/keyring.c

    r166 r235  
    5656    keyring->keys=NULL; 
    5757    } 
     58 
     59const ops_public_key_t * 
     60ops_get_public_key_from_data(const ops_key_data_t *data) 
     61    { return &data->pkey; } 
     62 
  • openpgpsdk/trunk/src/openssl_crypto.c

    r140 r235  
    3535    } 
    3636 
    37 static ops_hash_t md5={md5_init,md5_add,md5_finish}; 
     37static ops_hash_t md5={OPS_HASH_MD5,md5_init,md5_add,md5_finish}; 
    3838 
    3939void ops_hash_md5(ops_hash_t *hash) 
     
    6363    } 
    6464 
    65 static ops_hash_t sha1={sha1_init,sha1_add,sha1_finish}; 
     65static ops_hash_t sha1={OPS_HASH_SHA1,sha1_init,sha1_add,sha1_finish}; 
    6666 
    6767void ops_hash_sha1(ops_hash_t *hash) 
  • openpgpsdk/trunk/src/packet-parse.c

    r230 r235  
    533533    free(packet->raw); 
    534534    packet->raw=NULL; 
     535    } 
     536 
     537void ops_headers_free(ops_headers_t *headers) 
     538    { 
     539    int n; 
     540 
     541    for(n=0 ; n < headers->nheaders ; ++n) 
     542        { 
     543        free(headers->headers[n].key); 
     544        free(headers->headers[n].value); 
     545        } 
     546    free(headers->headers); 
     547    headers->headers=NULL; 
    535548    } 
    536549 
     
    555568    case OPS_PTAG_CT_SIGNATURE_HEADER: 
    556569    case OPS_PTAG_CT_ARMOUR_HEADER: 
    557     case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 
    558570    case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: 
     571    case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 
    559572    case OPS_PTAG_CT_UNARMOURED_TEXT: 
    560573    case OPS_PTAG_CT_ARMOUR_TRAILER: 
     574        break; 
     575 
     576    case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 
     577        ops_headers_free(&c->content.signed_cleartext_header.headers); 
    561578        break; 
    562579 
  • openpgpsdk/trunk/src/signature.c

    r177 r235  
    122122    ops_build_public_key(&mem,key,ops_false); 
    123123 
    124     hash_add_int(hash,0x99,1); 
    125     hash_add_int(hash,mem.length,2); 
     124    ops_hash_add_int(hash,0x99,1); 
     125    ops_hash_add_int(hash,mem.length,2); 
    126126    hash->add(hash,mem.buf,mem.length); 
    127127 
     
    132132                           const ops_public_key_t *key) 
    133133    { 
    134     switch(sig->hash_algorithm) 
     134    ops_hash_any(hash,sig->hash_algorithm); 
     135    hash->init(hash); 
     136    hash_add_key(hash,key); 
     137    } 
     138 
     139static void hash_add_trailer(ops_hash_t *hash,const ops_signature_t *sig, 
     140                             const ops_public_key_t *signer, 
     141                             const unsigned char *raw_packet) 
     142    { 
     143    if(sig->version == OPS_SIG_V4) 
    135144        { 
    136     case OPS_HASH_MD5: 
    137         ops_hash_md5(hash); 
     145        if(raw_packet) 
     146            hash->add(hash,raw_packet+sig->v4_hashed_data_start, 
     147                      sig->v4_hashed_data_length); 
     148        ops_hash_add_int(hash,sig->version,1); 
     149        ops_hash_add_int(hash,0xff,1); 
     150        ops_hash_add_int(hash,sig->v4_hashed_data_length,4); 
     151        } 
     152    else 
     153        { 
     154        ops_hash_add_int(hash,sig->type,1); 
     155        ops_hash_add_int(hash,sig->creation_time,4); 
     156        } 
     157    } 
     158 
     159static ops_boolean_t check_signature(const unsigned char *hash,unsigned length, 
     160                                     const ops_signature_t *sig, 
     161                                     const ops_public_key_t *signer) 
     162    { 
     163    ops_boolean_t ret; 
     164 
     165    printf(" hash="); 
     166    //    hashout[0]=0; 
     167    hexdump(hash,length); 
     168 
     169    switch(sig->key_algorithm) 
     170        { 
     171    case OPS_PKA_DSA: 
     172        ret=ops_dsa_verify(hash,length,&sig->signature.dsa,&signer->key.dsa); 
    138173        break; 
    139174 
    140     case OPS_HASH_SHA1: 
    141         ops_hash_sha1(hash); 
     175    case OPS_PKA_RSA: 
     176        ret=rsa_verify(sig->hash_algorithm,hash,length,&sig->signature.rsa, 
     177                       &signer->key.rsa); 
    142178        break; 
    143179 
     
    146182        } 
    147183 
    148     hash->init(hash); 
    149     hash_add_key(hash,key); 
    150     } 
    151  
    152 static void hash_add_trailer(ops_hash_t *hash,const ops_signature_t *sig, 
    153                              const ops_public_key_t *signer, 
    154                              const unsigned char *raw_packet) 
    155     { 
    156     if(sig->version == OPS_SIG_V4) 
    157         { 
    158         hash->add(hash,raw_packet+sig->v4_hashed_data_start, 
    159                   sig->v4_hashed_data_length); 
    160         hash_add_int(hash,sig->version,1); 
    161         hash_add_int(hash,0xff,1); 
    162         hash_add_int(hash,sig->v4_hashed_data_length,4); 
    163         } 
    164     else 
    165         { 
    166         hash_add_int(hash,sig->type,1); 
    167         hash_add_int(hash,sig->creation_time,4); 
    168         } 
    169     } 
    170  
    171 static ops_boolean_t check_signature(ops_hash_t *hash, 
    172                                      const ops_signature_t *sig, 
    173                                      const ops_public_key_t *signer) 
     184    return ret; 
     185    } 
     186 
     187static ops_boolean_t hash_and_check_signature(ops_hash_t *hash, 
     188                                              const ops_signature_t *sig, 
     189                                              const ops_public_key_t *signer) 
    174190    { 
    175191    int n; 
    176     ops_boolean_t ret; 
    177192    unsigned char hashout[OPS_MAX_HASH]; 
    178193 
    179194    n=hash->finish(hash,hashout); 
    180     printf(" hash="); 
    181     //    hashout[0]=0; 
    182     hexdump(hashout,n); 
    183  
    184     switch(sig->key_algorithm) 
    185         { 
    186     case OPS_PKA_DSA: 
    187         ret=ops_dsa_verify(hashout,n,&sig->signature.dsa,&signer->key.dsa); 
    188         break; 
    189  
    190     case OPS_PKA_RSA: 
    191         ret=rsa_verify(sig->hash_algorithm,hashout,n,&sig->signature.rsa, 
    192                        &signer->key.rsa); 
    193         break; 
    194  
    195     default: 
    196         assert(0); 
    197         } 
    198  
    199     return ret; 
     195 
     196    return check_signature(hashout,n,sig,signer); 
    200197    } 
    201198 
     
    206203    { 
    207204    hash_add_trailer(hash,sig,signer,raw_packet); 
    208     return check_signature(hash,sig,signer); 
     205    return hash_and_check_signature(hash,sig,signer); 
    209206    } 
    210207 
     
    222219    if(sig->version == OPS_SIG_V4) 
    223220        { 
    224         hash_add_int(&hash,0xb4,1); 
    225         hash_add_int(&hash,strlen(id->user_id),4); 
     221        ops_hash_add_int(&hash,0xb4,1); 
     222        ops_hash_add_int(&hash,strlen(id->user_id),4); 
    226223        hash.add(&hash,id->user_id,strlen(id->user_id)); 
    227224        } 
     
    246243    return finalise_signature(&hash,sig,signer,raw_packet); 
    247244    } 
     245 
     246ops_boolean_t 
     247ops_check_hash_signature(ops_hash_t *hash, 
     248                         const ops_signature_t *sig, 
     249                         const ops_public_key_t *signer) 
     250    { 
     251    if(sig->hash_algorithm != hash->algorithm) 
     252        return ops_false; 
     253 
     254    return finalise_signature(hash,sig,signer,NULL); 
     255    } 
     256     
    248257 
    249258/** 
     
    275284    init_signature(&sig->hash,&sig->sig,key); 
    276285 
    277     hash_add_int(&sig->hash,0xb4,1); 
    278     hash_add_int(&sig->hash,strlen(id->user_id),4); 
     286    ops_hash_add_int(&sig->hash,0xb4,1); 
     287    ops_hash_add_int(&sig->hash,strlen(id->user_id),4); 
    279288    sig->hash.add(&sig->hash,id->user_id,strlen(id->user_id)); 
    280289 
     
    337346    // add the packet from version number to end of hashed subpackets 
    338347    sig->hash.add(&sig->hash,sig->mem.buf,sig->unhashed_count_offset); 
    339     hash_add_int(&sig->hash,sig->sig.version,1); 
    340     hash_add_int(&sig->hash,0xff,1); 
    341     hash_add_int(&sig->hash,sig->hashed_data_length,4); 
     348    ops_hash_add_int(&sig->hash,sig->sig.version,1); 
     349    ops_hash_add_int(&sig->hash,0xff,1); 
     350    ops_hash_add_int(&sig->hash,sig->hashed_data_length,4); 
    342351 
    343352    // XXX: technically, we could figure out how big the signature is