Changeset 574

Show
Ignore:
Timestamp:
08/13/08 14:30:27
Author:
rachel
Message:

Implemented final part of command line application (list-packets).
Rationalised filenames.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openpgpsdk/trunk/Makefile

    r541 r574  
    1010default: 
    1111        @set -e; for d in $(SUBDIRS); do \ 
    12         (cd $$d; echo "+++ make in $$d"; make; echo "--- $$d"); \ 
     12        (cd $$d; echo "+++ make in $$d"; make -w; echo "** submake returns $$?\n"; echo "--- $$d"); \ 
    1313        done 
    1414 
  • openpgpsdk/trunk/include/openpgpsdk/armour.h

    r573 r574  
    2020 */ 
    2121 
     22#ifndef __OPS_ARMOUR_H__ 
     23#define __OPS_ARMOUR_H__ 
     24 
    2225#include "packet-parse.h" 
    2326#include "signature.h" 
     27 
     28unsigned ops_crc24(unsigned checksum,unsigned char c); 
    2429 
    2530void ops_reader_push_dearmour(ops_parse_info_t *parse_info, 
     
    4651void ops_writer_push_armoured(ops_create_info_t *info, ops_armor_type_t type); 
    4752 
     53#define CRC24_INIT 0xb704ceL 
     54 
     55#endif /* __OPS_ARMOUR_H__ */ 
     56 
    4857// EOF 
  • openpgpsdk/trunk/include/openpgpsdk/create.h

    r570 r574  
    2626#define OPS_CREATE_H 
    2727 
    28 #include "types.h" 
    29 #include "packet.h" 
    30 #include "crypto.h" 
    31 #include "memory.h" 
    32 #include "errors.h" 
    33 #include "keyring.h" 
     28#include <openpgpsdk/types.h> 
     29#include <openpgpsdk/packet.h> 
     30#include <openpgpsdk/crypto.h> 
     31#include <openpgpsdk/memory.h> 
     32#include <openpgpsdk/errors.h> 
     33#include <openpgpsdk/keyring.h> 
     34#include <openpgpsdk/writer.h> 
    3435 
    35 typedef struct ops_writer_info ops_writer_info_t; 
    3636/** 
    3737 * \ingroup Create 
    38  * the writer function prototype 
     38 * This struct contains the required information about how to write this stream 
    3939 */ 
    40 typedef ops_boolean_t ops_writer_t(const unsigned char *src, 
    41                                       unsigned length, 
    42                                       ops_error_t **errors, 
    43                                       ops_writer_info_t *winfo); 
    44 typedef ops_boolean_t ops_writer_finaliser_t(ops_error_t **errors, 
    45                                              ops_writer_info_t *winfo); 
    46 typedef void ops_writer_destroyer_t(ops_writer_info_t *winfo); 
     40struct ops_create_info 
     41    { 
     42    ops_writer_info_t winfo; 
     43    ops_error_t *errors;        /*!< an error stack */ 
     44    }; 
    4745 
    4846ops_create_info_t *ops_create_info_new(void); 
    4947void ops_create_info_delete(ops_create_info_t *info); 
    50 void *ops_writer_get_arg(ops_writer_info_t *winfo); 
    51 ops_boolean_t ops_stacked_write(const void *src,unsigned length, 
    52                                 ops_error_t **errors, 
    53                                 ops_writer_info_t *winfo); 
    5448 
    55 void ops_writer_set(ops_create_info_t *info, 
    56                     ops_writer_t *writer, 
    57                     ops_writer_finaliser_t *finaliser, 
    58                     ops_writer_destroyer_t *destroyer, 
    59                     void *arg); 
    60 void ops_writer_push(ops_create_info_t *info, 
    61                      ops_writer_t *writer, 
    62                      ops_writer_finaliser_t *finaliser, 
    63                      ops_writer_destroyer_t *destroyer, 
    64                      void *arg); 
    65 void ops_writer_pop(ops_create_info_t *info); 
    66 void ops_writer_generic_destroyer(ops_writer_info_t *winfo); 
    67 ops_boolean_t ops_writer_passthrough(const unsigned char *src, 
    68                                      unsigned length, 
    69                                      ops_error_t **errors, 
    70                                      ops_writer_info_t *winfo); 
     49ops_memory_t* ops_write_buf_from_file(const char *filename); 
     50int ops_write_file_from_buf(const char *filename, const char* buf, const size_t len, const ops_boolean_t overwrite); 
    7151 
    72 void ops_writer_set_fd(ops_create_info_t *info,int fd); 
    73 ops_boolean_t ops_writer_close(ops_create_info_t *info); 
    74  
    75 ops_boolean_t ops_write(const void *src,unsigned length, 
    76                         ops_create_info_t *opt); 
    77 ops_boolean_t ops_write_length(unsigned length,ops_create_info_t *opt); 
    78 ops_boolean_t ops_write_ptag(ops_content_tag_t tag,ops_create_info_t *opt); 
    79 ops_boolean_t ops_write_scalar(unsigned n,unsigned length, 
    80                                ops_create_info_t *opt); 
    81 ops_boolean_t ops_write_mpi(const BIGNUM *bn,ops_create_info_t *opt); 
    82 ops_boolean_t ops_write_encrypted_mpi(const BIGNUM *bn, ops_crypt_t* crypt, ops_create_info_t *info); 
    83 ops_boolean_t ops_write_ss_header(unsigned length,ops_content_tag_t type, 
    84                                   ops_create_info_t *opt); 
    85  
    86 void ops_fast_create_rsa_public_key(ops_public_key_t *key,time_t time, 
    87                                     BIGNUM *n,BIGNUM *e); 
    88 void ops_create_rsa_public_key(ops_public_key_t *key,time_t time, 
    89                                const BIGNUM *n,const BIGNUM *e); 
     52ops_boolean_t ops_calc_session_key_checksum(ops_pk_session_key_t *session_key, unsigned char *cs); 
    9053void ops_build_public_key(ops_memory_t *out,const ops_public_key_t *key, 
    9154                          ops_boolean_t make_packet); 
     55ops_boolean_t ops_write_struct_user_id(ops_user_id_t *id, 
     56                                       ops_create_info_t *info); 
    9257ops_boolean_t ops_write_struct_public_key(const ops_public_key_t *key, 
    93                                           ops_create_info_t *opt); 
    94 ops_boolean_t ops_write_rsa_public_key(time_t time,const BIGNUM *n, 
    95                                        const BIGNUM *e, 
    96                                        ops_create_info_t *opt); 
     58                                          ops_create_info_t *info); 
    9759 
    98 void ops_fast_create_user_id(ops_user_id_t *id,unsigned char *user_id); 
    99 ops_boolean_t ops_write_struct_user_id(ops_user_id_t *id, 
    100                                        ops_create_info_t *opt); 
    101 ops_boolean_t ops_write_user_id(const unsigned char *user_id,ops_create_info_t *opt); 
    102  
    103 void ops_create_rsa_secret_key(ops_secret_key_t *key,const BIGNUM *p, 
    104                                const BIGNUM *q,const BIGNUM *d, 
    105                                const BIGNUM *u,const BIGNUM *n, 
    106                                const BIGNUM *e); 
    107 void ops_fast_create_rsa_secret_key(ops_secret_key_t *key,time_t time, 
    108                                     BIGNUM *p,BIGNUM *q,BIGNUM *d,BIGNUM *u, 
    109                                     BIGNUM *n,BIGNUM *e); 
     60ops_boolean_t ops_write_ss_header(unsigned length,ops_content_tag_t type, 
     61                                  ops_create_info_t *info); 
    11062ops_boolean_t ops_write_struct_secret_key(const ops_secret_key_t *key, 
    11163                                          const unsigned char* passphrase, 
    11264                                          const size_t pplen, 
    11365                                          ops_create_info_t *info); 
    114  
     66ops_boolean_t ops_write_one_pass_sig(const ops_secret_key_t* skey, 
     67                                     const ops_hash_algorithm_t hash_alg, 
     68                                     const ops_sig_type_t sig_type, 
     69                                     ops_create_info_t* info); 
     70ops_boolean_t ops_write_literal_data_from_buf(const unsigned char *data,  
     71                                              const int maxlen,  
     72                                              const ops_literal_data_type_t type, 
     73                                              ops_create_info_t *info); 
    11574ops_pk_session_key_t *ops_create_pk_session_key(const ops_keydata_t *key); 
    116  
    117 void ops_create_m_buf(ops_pk_session_key_t *session_key, unsigned char *buf); 
    118  
    119 // RENAMED from ops_boolean_t ops_write_literal_data(const unsigned char *data,  
    120 ops_boolean_t ops_write_literal_data_from_buf(const unsigned char *data,  
    121                                      const int maxlen,  
    122                                      const ops_literal_data_type_t type, 
    123                                      ops_create_info_t *info); 
    124 ops_boolean_t ops_write_literal_data_from_file(const char *filename,  
    125                                                const ops_literal_data_type_t type, 
    126                                                ops_create_info_t *info); 
    127  
    128 ops_memory_t* ops_write_buf_from_file(const char *filename); 
    129 int ops_write_file_from_buf(const char* filename, const char* buf, const size_t len, const ops_boolean_t overwrite); 
    130  
    131 ops_boolean_t ops_write_symmetrically_encrypted_data(const unsigned char *data,  
    132                                                      const int len,  
    133                                                      ops_create_info_t *info); 
    134  
    135 ops_boolean_t ops_write_se_ip_data(const unsigned char *data, 
    136                                    const unsigned int len, 
    137                                    ops_crypt_t *crypt, 
    138                                    ops_create_info_t *info); 
    13975ops_boolean_t ops_write_pk_session_key(ops_create_info_t *info, 
    14076                                       ops_pk_session_key_t *pksk); 
    141 ops_boolean_t ops_calc_session_key_checksum(ops_pk_session_key_t *session_key, unsigned char *cs); 
    142 void ops_calc_mdc_hash(const unsigned char* preamble, const size_t sz_preamble, const unsigned char* data, const unsigned int len, unsigned char *hashed); 
     77ops_boolean_t ops_write_transferable_public_key(const ops_keydata_t *key, ops_boolean_t armoured, ops_create_info_t *info); 
     78ops_boolean_t ops_write_transferable_secret_key(const ops_keydata_t *key, const unsigned char* passphrase, const size_t pplen, ops_boolean_t armoured, ops_create_info_t *info); 
    14379 
    144 ops_boolean_t ops_write_one_pass_sig(const ops_secret_key_t* skey, const ops_hash_algorithm_t hash_alg, const ops_sig_type_t sig_type, ops_create_info_t* info); 
     80#endif /*OPS_CREATE_H*/ 
    14581 
    146 ops_boolean_t ops_write_transferable_public_key(const ops_keydata_t *key, ops_boolean_t armoured, ops_create_info_t *info); 
    147 ops_boolean_t ops_write_transferable_secret_key(const ops_keydata_t *key, const unsigned char* passphrase, size_t pplen, ops_boolean_t armoured, ops_create_info_t *info); 
    148  
    149 #endif 
     82// eof 
  • openpgpsdk/trunk/include/openpgpsdk/crypto.h

    r570 r574  
    160160                             const struct ops_key_data *key); 
    161161 
    162 void ops_encrypt_file(const char* input_filename, const char* output_filename, const ops_keydata_t *pub_key, const ops_boolean_t use_armour, const ops_boolean_t allow_overwrite); 
    163 void ops_decrypt_file(const char* input_filename, const char* output_filename, ops_keyring_t *keyring, const ops_boolean_t use_armour, const ops_boolean_t allow_overwrite,ops_parse_cb_t* cb_get_passphrase); 
     162ops_boolean_t ops_encrypt_file(const char* input_filename, const char* output_filename, const ops_keydata_t *pub_key, const ops_boolean_t use_armour, const ops_boolean_t allow_overwrite); 
     163ops_boolean_t ops_decrypt_file(const char* input_filename, const char* output_filename, ops_keyring_t *keyring, const ops_boolean_t use_armour, const ops_boolean_t allow_overwrite,ops_parse_cb_t* cb_get_passphrase); 
    164164 
    165165// Keys 
  • openpgpsdk/trunk/include/openpgpsdk/readerwriter.h

    r570 r574  
    2525#include <openpgpsdk/memory.h> 
    2626#include <openpgpsdk/create.h> 
    27  
    28 /** 
    29  * \ingroup Create 
    30  * This struct contains the required information about one writer 
    31  */ 
    32 struct ops_writer_info 
    33     { 
    34     ops_writer_t *writer; 
    35     ops_writer_finaliser_t *finaliser; 
    36     ops_writer_destroyer_t *destroyer; 
    37     void *arg; 
    38     ops_writer_info_t *next; 
    39     }; 
    40  
    41 /** 
    42  * \ingroup Create 
    43  * This struct contains the required information about how to write this stream 
    44  */ 
    45 struct ops_create_info 
    46     { 
    47     ops_writer_info_t winfo; 
    48     ops_error_t *errors;        /*!< an error stack */ 
    49     }; 
    5027 
    5128// 
  • openpgpsdk/trunk/include/openpgpsdk/std_print.h

    r570 r574  
    4343//void ops_print_secret_key(const ops_content_tag_t type, const ops_secret_key_t* skey); 
    4444int ops_print_packet(const ops_parser_content_t *content_); 
     45void ops_list_packets(char *filename, ops_boolean_t armour, ops_keyring_t* pubring, ops_parse_cb_t* cb_get_passphrase); 
     46 
    4547#endif 
  • openpgpsdk/trunk/src/app/openpgp.c

    r572 r574  
    3737#include "openpgpsdk/validate.h" 
    3838#include "openpgpsdk/readerwriter.h" 
     39#include "openpgpsdk/std_print.h" 
    3940 
    4041#define DEFAULT_NUMBITS 1024 
     
    5253static const char* usage_clearsign="%s --clearsign --userid=<userid> --filename=<filename> [--homedir=<homedir>]\n"; 
    5354static const char* usage_verify="%s --verify --filename=<filename> [--homedir=<homedir>] [--armour]\n"; 
     55static const char* usage_list_packets="%s --list-packets --filename=<filename> [--homedir=<homedir>] [--armour]\n"; 
    5456 
    5557static const char* pname; 
     
    6870CLEARSIGN, 
    6971VERIFY, 
     72LIST_PACKETS, 
     73 
    7074// options 
    7175KEYRING, 
     
    9397    { "clearsign", no_argument, NULL, CLEARSIGN }, 
    9498    { "verify", no_argument, NULL, VERIFY }, 
     99 
     100    { "list-packets", no_argument, NULL, LIST_PACKETS }, 
    95101 
    96102    // options 
     
    228234            break; 
    229235 
     236        case LIST_PACKETS: 
     237            cmd=LIST_PACKETS; 
     238            break; 
     239 
    230240            // option 
    231241 
     
    428438 
    429439        // write public key 
    430 #ifdef TMP 
    431         ops_setup_memory_write(&cinfo, &mem, 128); 
    432         ops_write_transferable_public_key(mykeydata, ops_true, cinfo); 
    433         ops_keyring_read_from_mem(pubring, mem); 
    434         ops_teardown_memory_write(cinfo,mem); 
    435  
    436         // write secret key 
    437         ops_setup_memory_write(&cinfo, &mem, 128); 
    438         ops_write_transferable_secret_key(mykeydata, NULL, 0, ops_true, cinfo); 
    439         ops_keyring_read_from_mem(secring, mem); 
    440         ops_teardown_memory_write(cinfo,mem); 
    441 #else 
    442440        // append to keyrings 
    443441        fd=ops_setup_file_append(&cinfo, pubring_name); 
     
    461459            exit(-1); 
    462460            } 
    463 #endif 
     461 
    464462        ops_keydata_free(mykeydata); 
    465463        break; 
     
    576574        break; 
    577575 
     576    case LIST_PACKETS: 
     577        if (!got_filename) 
     578            { 
     579            print_usage(usage_list_packets, pname); 
     580            exit(-1); 
     581            } 
     582        ops_list_packets(opt_filename, armour, pubring, callback_cmd_get_passphrase_from_cmdline); 
     583        break; 
     584 
    578585    default: 
    579586        print_usage(usage,pname); 
  • openpgpsdk/trunk/src/lib/Makefile.template

    r546 r574  
    88all: Makefile headers .depend lib 
    99 
    10 LIBOBJS = adv_packet-parse.o adv_util.o adv_openssl_crypto.o adv_accumulate.o \ 
    11         adv_memory.o adv_fingerprint.o adv_hash.o adv_keyring.o \ 
    12         adv_signature.o adv_compress.o adv_packet-show.o adv_create.o \ 
    13         adv_validate.o adv_lists.o adv_armour.o adv_errors.o \ 
    14     adv_writer_encrypt_se_ip.o adv_writer_encrypt.o \ 
    15     adv_writer_stream_encrypt_se_ip.o \ 
    16         adv_symmetric.o adv_crypto.o random.o adv_readerwriter.o \ 
    17     std_encrypt.o std_keyring.o std_print.o std_signature.o 
     10LIBOBJS = packet-parse.o packet-print.o packet-show.o \ 
     11        util.o openssl_crypto.o accumulate.o \ 
     12        memory.o fingerprint.o hash.o keyring.o \ 
     13        signature.o compress.o create.o \ 
     14        validate.o lists.o errors.o \ 
     15        symmetric.o crypto.o random.o readerwriter.o \ 
     16        reader.o reader_fd.o reader_mem.o \ 
     17        reader_armoured.o reader_hashed.o reader_encrypted.o \ 
     18        writer_fd.o writer_memory.o \ 
     19        writer.o writer_skey_checksum.o  writer_armour.o \ 
     20        writer_encrypt_se_ip.o writer_encrypt.o \ 
     21        writer_stream_encrypt_se_ip.o 
    1822 
    1923headers: 
  • openpgpsdk/trunk/src/lib/compress.c

    r571 r574  
    6666    } compress_arg_t; 
    6767 
    68 #define ERR(err)        do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; ops_parse_cb(&content,cbinfo); return -1; } while(0) 
    69  
    7068// \todo remove code duplication between this and bzip2_compressed_data_reader 
    7169static int zlib_compressed_data_reader(void *dest,size_t length, 
     
    7775    assert(arg->type==OPS_C_ZIP || arg->type==OPS_C_ZLIB); 
    7876 
    79     ops_parser_content_t content; 
     77    //ops_parser_content_t content; 
    8078    int saved=length; 
    8179 
     
    8785        { 
    8886        if(arg->inflate_ret != Z_STREAM_END) 
    89             ERR("Compressed data didn't end when region ended."); 
     87            OPS_ERROR(cbinfo->errors, OPS_E_P_DECOMPRESSION_ERROR,"Compressed data didn't end when region ended."); 
    9088        /* 
    9189          else 
     
    133131                if(!arg->region->indeterminate 
    134132                   && arg->region->length_read != arg->region->length) 
    135                     ERR("Compressed stream ended before packet end."); 
     133                    OPS_ERROR(cbinfo->errors,OPS_E_P_DECOMPRESSION_ERROR,"Compressed stream ended before packet end."); 
    136134                } 
    137135            else if(ret != Z_OK) 
    138136                { 
    139137                fprintf(stderr,"ret=%d\n",ret); 
    140                 ERR(arg->zstream.msg); 
     138                OPS_ERROR(cbinfo->errors,OPS_E_P_DECOMPRESSION_ERROR, arg->zstream.msg); 
    141139                } 
    142140            arg->inflate_ret=ret; 
     
    163161    assert(arg->type==OPS_C_BZIP2); 
    164162 
    165     ops_parser_content_t content; 
     163    //ops_parser_content_t content; 
    166164    int saved=length; 
    167165 
     
    173171        { 
    174172        if(arg->inflate_ret != BZ_STREAM_END) 
    175             ERR("Compressed data didn't end when region ended."); 
     173            OPS_ERROR(cbinfo->errors, OPS_E_P_DECOMPRESSION_ERROR,"Compressed data didn't end when region ended."); 
    176174        } 
    177175 
     
    214212                if(!arg->region->indeterminate 
    215213                   && arg->region->length_read != arg->region->length) 
    216                     ERR("Compressed stream ended before packet end."); 
     214                    OPS_ERROR(cbinfo->errors,OPS_E_P_DECOMPRESSION_ERROR,"Compressed stream ended before packet end."); 
    217215                } 
    218216            else if(ret != BZ_OK) 
    219217                { 
    220                 fprintf(stderr,"ret=%d\n",ret); 
    221         //              ERR(arg->bzstream.msg); //\todo add error handling 
     218                OPS_ERROR_1(cbinfo->errors,OPS_E_P_DECOMPRESSION_ERROR,"Invalid return %d from BZ2_bzDecompress", ret); 
    222219                } 
    223220            arg->inflate_ret=ret; 
  • openpgpsdk/trunk/src/lib/create.c

    r573 r574  
    4242#endif 
    4343 
     44#include <openpgpsdk/writer.h> 
    4445#include <openpgpsdk/final.h> 
    4546 
    4647static int debug=0; 
    47  
    48 static ops_boolean_t writer_info_finalise(ops_error_t **errors, 
    49                                           ops_writer_info_t *winfo); 
    50  
    51 /* 
    52  * return true if OK, otherwise false 
    53  */ 
    54 static ops_boolean_t base_write(const void *src,unsigned length, 
    55                                 ops_create_info_t *info) 
    56     { 
    57     return info->winfo.writer(src,length,&info->errors,&info->winfo); 
    58     } 
    59  
    60 /** 
    61  * \ingroup Create 
    62  * 
    63  * \param src 
    64  * \param length 
    65  * \param info 
    66  * \return 1 if OK, otherwise 0 
    67  */ 
    68  
    69 ops_boolean_t ops_write(const void *src,unsigned length, 
    70                         ops_create_info_t *info) 
    71     { 
    72     return base_write(src,length,info); 
    73     } 
    74  
    75 /** 
    76  * \ingroup Create 
    77  * \param n 
    78  * \param length 
    79  * \param info 
    80  * \return ops_true if OK, otherwise ops_false 
    81  */ 
    82  
    83 ops_boolean_t ops_write_scalar(unsigned n,unsigned length, 
    84                                ops_create_info_t *info) 
    85     { 
    86     while(length-- > 0) 
    87         { 
    88         unsigned char c[1]; 
    89  
    90         c[0]=n >> (length*8); 
    91         if(!base_write(c,1,info)) 
    92             return ops_false; 
    93         } 
    94     return ops_true; 
    95     } 
    96  
    97 /**  
    98  * \ingroup Create 
    99  * \param bn 
    100  * \param info 
    101  * \return 1 if OK, otherwise 0 
    102  */ 
    103  
    104 ops_boolean_t ops_write_mpi(const BIGNUM *bn,ops_create_info_t *info) 
    105     { 
    106     unsigned char buf[8192]; 
    107     int bits=BN_num_bits(bn); 
    108  
    109     assert(bits <= 65535); 
    110     BN_bn2bin(bn,buf); 
    111     return ops_write_scalar(bits,2,info) 
    112         && ops_write(buf,(bits+7)/8,info); 
    113     } 
    114  
    115 /**  
    116  * \ingroup Create 
    117  * \param tag 
    118  * \param info 
    119  * \return 1 if OK, otherwise 0 
    120  */ 
    121  
    122 ops_boolean_t ops_write_ptag(ops_content_tag_t tag,ops_create_info_t *info) 
    123     { 
    124     unsigned char c[1]; 
    125  
    126     c[0]=tag|OPS_PTAG_ALWAYS_SET|OPS_PTAG_NEW_FORMAT; 
    127  
    128     return base_write(c,1,info); 
    129     } 
    130  
    131 /**  
    132  * \ingroup Create 
    133  * \param length 
    134  * \param info 
    135  * \return 1 if OK, otherwise 0 
    136  */ 
    137  
    138 ops_boolean_t ops_write_length(unsigned length,ops_create_info_t *info) 
    139     { 
    140     unsigned char c[2]; 
    141  
    142     if(length < 192) 
    143         { 
    144         c[0]=length; 
    145         return base_write(c,1,info); 
    146         } 
    147     else if(length < 8384) 
    148         { 
    149         c[0]=((length-192) >> 8)+192; 
    150         c[1]=(length-192)%256; 
    151         return base_write(c,2,info); 
    152         } 
    153     return ops_write_scalar(0xff,1,info) && ops_write_scalar(length,4,info); 
    154     } 
    15548 
    15649/**  
     
    321214    } 
    322215 
    323 typedef struct 
    324     { 
    325     ops_hash_algorithm_t hash_algorithm; 
    326     ops_hash_t hash; 
    327     unsigned char *hashed; 
    328     } skey_checksum_arg_t; 
    329  
    330 static ops_boolean_t skey_checksum_writer(const unsigned char *src, const unsigned length, ops_error_t **errors, ops_writer_info_t *winfo) 
    331     { 
    332     skey_checksum_arg_t *arg=ops_writer_get_arg(winfo); 
    333     ops_boolean_t rtn=ops_true; 
    334  
    335     // add contents to hash 
    336     arg->hash.add(&arg->hash, src, length); 
    337  
    338     // write to next stacked writer 
    339     rtn=ops_stacked_write(src,length,errors,winfo); 
    340  
    341     // tidy up and return 
    342     return rtn; 
    343     } 
    344  
    345 static ops_boolean_t skey_checksum_finaliser(ops_error_t **errors __attribute__((unused)), ops_writer_info_t *winfo) 
    346     { 
    347     skey_checksum_arg_t *arg=ops_writer_get_arg(winfo); 
    348     arg->hash.finish(&arg->hash, arg->hashed); 
    349     return ops_true; 
    350     } 
    351  
    352 static void skey_checksum_destroyer(ops_writer_info_t* winfo) 
    353     { 
    354     skey_checksum_arg_t *arg=ops_writer_get_arg(winfo); 
    355     free(arg); 
    356     } 
    357  
    358 void ops_push_skey_checksum_writer(ops_create_info_t *cinfo, ops_secret_key_t *skey) 
    359     { 
    360     //    OPS_USED(info); 
    361     // XXX: push a SHA-1 checksum writer (and change s2k to 254). 
    362     skey_checksum_arg_t *arg=ops_mallocz(sizeof *arg); 
    363  
    364     // configure the arg 
    365     arg->hash_algorithm=skey->hash_algorithm; 
    366     arg->hashed=&skey->checkhash[0]; 
    367  
    368     // init the hash 
    369     ops_hash_any(&arg->hash, arg->hash_algorithm); 
    370     arg->hash.init(&arg->hash); 
    371  
    372     ops_writer_push(cinfo, skey_checksum_writer, skey_checksum_finaliser, skey_checksum_destroyer, arg); 
    373     } 
    374   
    375216/* Note that we support v3 keys here because they're needed for 
    376217 * for verification - the writer doesn't allow them, though */ 
     
    871712    { return ops_mallocz(sizeof(ops_create_info_t)); } 
    872713 
    873 /* Note that we finalise from the top down, so we don't use writers below 
    874  * that have already been finalised 
    875  */ 
    876 static ops_boolean_t writer_info_finalise(ops_error_t **errors, 
    877                                           ops_writer_info_t *winfo) 
    878     { 
    879     ops_boolean_t ret=ops_true; 
    880  
    881     if(winfo->finaliser) 
    882         { 
    883         ret=winfo->finaliser(errors,winfo); 
    884         winfo->finaliser=NULL; 
    885         } 
    886     if(winfo->next && !writer_info_finalise(errors,winfo->next)) 
    887         { 
    888         winfo->finaliser=NULL; 
    889         return ops_false; 
    890         } 
    891     return ret; 
    892     } 
    893  
    894 static void writer_info_delete(ops_writer_info_t *winfo) 
    895     { 
    896     // we should have finalised before deleting 
    897     assert(!winfo->finaliser); 
    898     if(winfo->next) 
    899         { 
    900         writer_info_delete(winfo->next); 
    901         free(winfo->next); 
    902         winfo->next=NULL; 
    903         } 
    904     if(winfo->destroyer) 
    905         { 
    906         winfo->destroyer(winfo); 
    907         winfo->destroyer=NULL; 
    908         } 
    909     winfo->writer=NULL; 
    910     } 
    911  
    912714/** 
    913715 * \ingroup Create 
     
    923725    free(info); 
    924726    } 
    925  
    926 typedef struct 
    927     { 
    928     int fd; 
    929     } writer_fd_arg_t; 
    930  
    931 static ops_boolean_t fd_writer(const unsigned char *src,unsigned length, 
    932                                ops_error_t **errors, 
    933                                ops_writer_info_t *winfo) 
    934     { 
    935     writer_fd_arg_t *arg=ops_writer_get_arg(winfo); 
    936     int n=write(arg->fd,src,length); 
    937  
    938     if(n == -1) 
    939         { 
    940         OPS_SYSTEM_ERROR_1(errors,OPS_E_W_WRITE_FAILED,"write", 
    941                            "file descriptor %d",arg->fd); 
    942         return ops_false; 
    943         } 
    944  
    945     if((unsigned)n != length) 
    946         { 
    947         OPS_ERROR_1(errors,OPS_E_W_WRITE_TOO_SHORT, 
    948                     "file descriptor %d",arg->fd); 
    949         return ops_false; 
    950         } 
    951  
    952     return ops_true; 
    953     } 
    954  
    955 static void fd_destroyer(ops_writer_info_t *winfo) 
    956     { 
    957     free(ops_writer_get_arg(winfo)); 
    958     } 
    959  
    960 /** 
    961  * \ingroup Create 
    962  * 
    963  * Set the writer in info to be a stock writer that writes to a file 
    964  * descriptor. If another writer has already been set, then that is 
    965  * first destroyed. 
    966  *  
    967  * \param info The info structure 
    968  * \param fd The file descriptor 
    969  * 
    970  */ 
    971  
    972 void ops_writer_set_fd(ops_create_info_t *info,int fd) 
    973     { 
    974     writer_fd_arg_t *arg=malloc(sizeof *arg); 
    975  
    976     arg->fd=fd; 
    977     ops_writer_set(info,fd_writer,NULL,fd_destroyer,arg); 
    978     } 
    979  
    980 /** 
    981  * \ingroup Create 
    982  * 
    983  * Set a writer in info. There should not be another writer set. 
    984  * 
    985  * \param info The info structure 
    986  * \param writer The writer 
    987  * \param destroyer The destroyer 
    988  * \param arg The argument for the writer and destroyer 
    989  */ 
    990 void ops_writer_set(ops_create_info_t *info, 
    991                     ops_writer_t *writer, 
    992                     ops_writer_finaliser_t *finaliser, 
    993                     ops_writer_destroyer_t *destroyer, 
    994                     void *arg) 
    995     { 
    996     assert(!info->winfo.writer); 
    997     info->winfo.writer=writer; 
    998     info->winfo.finaliser=finaliser; 
    999     info->winfo.destroyer=destroyer; 
    1000     info->winfo.arg=arg; 
    1001     } 
    1002  
    1003 /** 
    1004  * \ingroup Create 
    1005  * 
    1006  * Push a writer in info. There must already be another writer set. 
    1007  * 
    1008  * \param info The info structure 
    1009  * \param writer The writer 
    1010  * \param destroyer The destroyer 
    1011  * \param arg The argument for the writer and destroyer 
    1012  */ 
    1013 void ops_writer_push(ops_create_info_t *info, 
    1014                      ops_writer_t *writer, 
    1015                      ops_writer_finaliser_t *finaliser, 
    1016                      ops_writer_destroyer_t *destroyer, 
    1017                      void *arg) 
    1018     { 
    1019     ops_writer_info_t *copy=ops_mallocz(sizeof *copy); 
    1020  
    1021     assert(info->winfo.writer); 
    1022     *copy=info->winfo; 
    1023     info->winfo.next=copy; 
    1024  
    1025     info->winfo.writer=writer; 
    1026     info->winfo.finaliser=finaliser; 
    1027     info->winfo.destroyer=destroyer; 
    1028     info->winfo.arg=arg; 
    1029     } 
    1030  
    1031 void ops_writer_pop(ops_create_info_t *info) 
    1032     {  
    1033     ops_writer_info_t *next; 
    1034  
    1035     // Make sure the finaliser has been called. 
    1036     assert(!info->winfo.finaliser); 
    1037     // Make sure this is a stacked writer 
    1038     assert(info->winfo.next); 
    1039     if(info->winfo.destroyer) 
    1040         info->winfo.destroyer(&info->winfo); 
    1041  
    1042     next=info->winfo.next; 
    1043     info->winfo=*next; 
    1044  
    1045     free(next); 
    1046     } 
    1047  
    1048 /** 
    1049  * \ingroup Create 
    1050  * 
    1051  * Close the writer currently set in info. 
    1052  * 
    1053  * \param info The info structure 
    1054  */ 
    1055 ops_boolean_t ops_writer_close(ops_create_info_t *info) 
    1056     { 
    1057     ops_boolean_t ret=writer_info_finalise(&info->errors,&info->winfo); 
    1058  
    1059     writer_info_delete(&info->winfo); 
    1060  
    1061     return ret; 
    1062     } 
    1063  
    1064 /** 
    1065  * \ingroup Create 
    1066  * 
    1067  * Get the arg supplied to ops_create_info_set_writer(). 
    1068  * 
    1069  * \param winfo The writer_info structure 
    1070  * \return The arg 
    1071  */ 
    1072 void *ops_writer_get_arg(ops_writer_info_t *winfo) 
    1073     { return winfo->arg; } 
    1074  
    1075 /** 
    1076  * \ingroup Create 
    1077  * 
    1078  * Write to the next writer down in the stack. 
    1079  * 
    1080  * \param src The data to write. 
    1081  * \param length The length of src. 
    1082  * \param flags The writer flags. 
    1083  * \param errors A place to store errors. 
    1084  * \param info The writer_info structure. 
    1085  * \return Success - if ops_false, then errors should contain the error. 
    1086  */ 
    1087 ops_boolean_t ops_stacked_write(const void *src,unsigned length, 
    1088                                 ops_error_t **errors,ops_writer_info_t *winfo) 
    1089     { 
    1090     return winfo->next->writer(src,length,errors,winfo->next); 
    1091     } 
    1092  
    1093 /** 
    1094  * \ingroup Create 
    1095  * 
    1096  * Free the arg. Many writers just have a malloc()ed lump of storage, this 
    1097  * function releases it. 
    1098  * 
    1099  * \param winfo the info structure. 
    1100  */ 
    1101 void ops_writer_generic_destroyer(ops_writer_info_t *winfo) 
    1102     { free(ops_writer_get_arg(winfo)); } 
    1103  
    1104 /** 
    1105  * \ingroup Create 
    1106  * 
    1107  * A writer that just writes to the next one down. Useful for when you 
    1108  * want to insert just a finaliser into the stack. 
    1109  */ 
    1110 ops_boolean_t ops_writer_passthrough(const unsigned char *src, 
    1111                                      unsigned length, 
    1112                                      ops_error_t **errors, 
    1113                                      ops_writer_info_t *winfo) 
    1114     { return ops_stacked_write(src,length,errors,winfo); } 
    1115  
    1116727