Changeset 336

Show
Ignore:
Timestamp:
01/25/06 18:40:09
Author:
ben
Message:

Another step closer to decryption.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openpgpsdk/trunk/examples/decrypt.c

    r335 r336  
    1414 
    1515static ops_parse_cb_return_t 
    16 cb_secret_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 
     16callback(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 
    1717    { 
    18     //    const ops_parser_content_union_t *content=&content_->content; 
    19     //    char buffer[1024]
    20     //    size_t n
     18    const ops_parser_content_union_t *content=&content_->content; 
     19    static ops_boolean_t skipping
     20    static const ops_key_data_t *decrypter
    2121 
    2222    OPS_USED(cbinfo); 
    2323 
    24     switch(content_->tag) 
     24    if(content_->tag != OPS_PTAG_CT_UNARMOURED_TEXT && skipping) 
    2525        { 
    26     case OPS_PARSER_PTAG: 
    27     case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: // we get these because we didn't prompt 
    28     case OPS_PARSER_ERROR_UNKNOWN_TAG: 
    29     case OPS_PARSER_ERROR_PACKET_CONSUMED: // only happens after another error we've deemed to be OK 
    30     case OPS_PTAG_CT_SIGNATURE_HEADER: 
    31     case OPS_PTAG_CT_SIGNATURE_FOOTER: 
    32     case OPS_PTAG_CT_SIGNATURE: 
    33     case OPS_PTAG_CT_TRUST: 
    34         break; 
    35  
    36     case OPS_PTAG_CMD_GET_PASSPHRASE: 
    37         /* 
    38         printf("Passphrase: "); 
    39         fgets(buffer,sizeof buffer,stdin); 
    40         n=strlen(buffer); 
    41         if(n && buffer[n-1] == '\n') 
    42             buffer[--n]='\0'; 
    43         *content->passphrase=malloc(n+1); 
    44         strcpy(*content->passphrase,buffer); 
    45         return OPS_KEEP_MEMORY; 
    46         */ 
    47         // we don't want to prompt when reading the keyring 
    48         break; 
    49  
    50     default: 
    51         fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag, 
    52                 content_->tag); 
    53         assert(0); 
    54         exit(1); 
     26        puts("...end of skip"); 
     27        skipping=ops_false; 
    5528        } 
    56  
    57     return OPS_RELEASE_MEMORY; 
    58     } 
    59  
    60 static ops_parse_cb_return_t 
    61 callback(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 
    62     { 
    63     //    const ops_parser_content_union_t *content=&content_->content; 
    64     OPS_USED(cbinfo); 
    6529 
    6630    switch(content_->tag) 
    6731        { 
     32    case OPS_PTAG_CT_UNARMOURED_TEXT: 
     33        if(!skipping) 
     34            { 
     35            puts("Skipping..."); 
     36            skipping=ops_true; 
     37            } 
     38        fwrite(content->unarmoured_text.data,1, 
     39               content->unarmoured_text.length,stdout); 
     40        break; 
     41 
     42    case OPS_PTAG_CT_ARMOUR_HEADER: 
     43    case OPS_PARSER_PTAG: 
     44        break; 
     45 
     46    case OPS_PTAG_CT_PK_SESSION_KEY: 
     47        if(decrypter) 
     48            break; 
     49 
     50        decrypter=ops_keyring_find_key_by_id(&keyring, 
     51                                             content->pk_session_key.key_id); 
     52        if(!decrypter) 
     53            break; 
     54        break; 
     55         
    6856    default: 
    6957        fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag, 
     
    10896    ops_init(); 
    10997 
    110     memset(&keyring,'\0',sizeof keyring); 
    111  
    112     pinfo=ops_parse_info_new(); 
    113  
    114     fd=open(keyfile,O_RDONLY); 
    115     if(fd < 0) 
    116         { 
    117         perror(keyfile); 
    118         exit(1); 
    119         } 
    120  
    121     ops_reader_set_fd(pinfo,fd); 
    122  
    123     ops_parse_cb_set(pinfo,cb_secret_key,NULL); 
    124  
    125     ops_parse_and_accumulate(&keyring,pinfo); 
    126  
    127     close(fd); 
     98    ops_keyring_read(&keyring,keyfile); 
    12899 
    129100    pinfo=ops_parse_info_new(); 
  • openpgpsdk/trunk/examples/packet-dump.c

    r335 r336  
    77#include <openpgpsdk/armour.h> 
    88#include <openpgpsdk/crypto.h> 
     9#include <openpgpsdk/keyring.h> 
    910 
    1011#include <unistd.h> 
     
    1718static int indent=0; 
    1819static const char *pname; 
     20static ops_keyring_t keyring; 
    1921 
    2022static void print_indent() 
     
    166168    } 
    167169 
     170static void print_escaped(const unsigned char *data,size_t length) 
     171    { 
     172    while(length-- > 0) 
     173        { 
     174        if((*data >= 0x20 && *data < 0x7f && *data != '%') || *data == '\n') 
     175            putchar(*data); 
     176        else 
     177            printf("%%%02x",*data); 
     178        ++data; 
     179        } 
     180    } 
     181 
    168182static void print_string(const char *name,const char *str) 
    169183    { 
    170184    print_name(name); 
    171     while(*str) 
    172         { 
    173         if(*str >= 0x20 && *str < 0x7f && *str != '%') 
    174             putchar(*str); 
    175         else 
    176             printf("%%%02x",(unsigned char)*str); 
    177         ++str; 
    178         } 
     185    print_escaped(str,strlen(str)); 
    179186    putchar('\n'); 
    180187    } 
     
    323330    ops_text_t *text; 
    324331    char *str; 
     332    ops_key_data_t *decrypter; 
     333    const ops_secret_key_t *secret; 
     334    static ops_boolean_t unarmoured; 
    325335 
    326336    OPS_USED(cbinfo); 
     337 
     338    if(unarmoured && content_->tag != OPS_PTAG_CT_UNARMOURED_TEXT) 
     339        { 
     340        unarmoured=ops_false; 
     341        puts("UNARMOURED TEXT ends"); 
     342        } 
    327343 
    328344    switch(content_->tag) 
     
    342358 
    343359    case OPS_PARSER_PTAG: 
    344  
    345         if (content->ptag.content_tag==OPS_PTAG_CT_PUBLIC_KEY) 
     360        if(content->ptag.content_tag == OPS_PTAG_CT_PUBLIC_KEY) 
    346361            { 
    347362            indent=0; 
     
    359374        print_tagname(ops_str_from_single_packet_tag(content->ptag.content_tag)); 
    360375        */ 
     376        break; 
     377 
     378    case OPS_PTAG_CT_SE_DATA: 
     379        print_tagname("SYMMETRIC ENCRYPTED DATA"); 
    361380        break; 
    362381 
     
    783802        break; 
    784803 
    785     case OPS_PTAG_CMD_GET_PASSPHRASE: 
     804    case OPS_PARSER_CMD_GET_PASSPHRASE: 
    786805        printf(">>> ASKED FOR PASSPHRASE <<<\n"); 
    787806        break; 
     
    838857 
    839858    case OPS_PTAG_CT_UNARMOURED_TEXT: 
    840         print_tagname("UNARMOURED TEXT"); 
    841         print_block("unarmoured text",content->unarmoured_text.data, 
    842                     content->unarmoured_text.length); 
     859        if(!unarmoured) 
     860            { 
     861            print_tagname("UNARMOURED TEXT"); 
     862            unarmoured=ops_true; 
     863            } 
     864        putchar('['); 
     865        print_escaped(content->unarmoured_text.data, 
     866                      content->unarmoured_text.length); 
     867        putchar(']'); 
    843868        break; 
    844869 
     
    871896            assert(0); 
    872897            } 
     898 
     899        /* Now get hold of session key for later on */ 
     900 
     901        decrypter=ops_keyring_find_key_by_id(&keyring, 
     902                                             content->pk_session_key.key_id); 
     903        if(!decrypter || !ops_key_is_secret(decrypter)) 
     904            break; 
     905 
     906        puts("[Decryption key found in keyring]"); 
     907 
     908        secret=ops_get_secret_key_from_data(decrypter); 
     909        while(!secret) 
     910            { 
     911            /* then it must be encrypted */ 
     912            char *phrase=ops_get_passphrase(); 
     913            secret=ops_decrypt_secret_key_from_data(decrypter,phrase); 
     914            free(phrase); 
     915            } 
     916         
    873917        break; 
    874918 
     
    900944    ops_boolean_t buffer_read=ops_false; 
    901945    unsigned char buffer[10240]; 
     946    const char *keyring_file=NULL; 
    902947 
    903948    pname=argv[0]; 
    904949 
    905     while((ch=getopt(argc,argv,"abB")) != -1) 
     950    while((ch=getopt(argc,argv,"abBk:")) != -1) 
    906951        switch(ch) 
    907952            { 
     
    917962        case 'B': 
    918963            buffer_read=ops_true; 
     964            break; 
     965 
     966        case 'k': 
     967            keyring_file=optarg; 
    919968            break; 
    920969 
     
    927976    if(argc != 1) 
    928977        usage(); 
     978 
     979    if(keyring_file) 
     980        ops_keyring_read(&keyring,keyring_file); 
    929981 
    930982    fd=open(argv[0],O_RDONLY); 
  • openpgpsdk/trunk/include/openpgpsdk/crypto.h

    r333 r336  
    22 */ 
    33 
     4#ifndef OPS_CRYPTO_H 
     5#define OPS_CRYPTO_H 
     6 
    47#include "util.h" 
    58#include "packet.h" 
    6  
    7 #ifndef OPS_CRYPTO_H 
    8 #define OPS_CRYPTO_H 
     9#include "packet-parse.h" 
    910 
    1011#define OPS_MAX_HASH    64 
     
    2324    ops_hash_add_t *add; 
    2425    ops_hash_finish_t *finish; 
     26    void *data; 
     27    }; 
     28 
     29typedef void ops_decrypt_init_t(ops_decrypt_t *decrypt); 
     30typedef size_t ops_decrypt_decrypt_t(ops_decrypt_t *decrypt,void *out, 
     31                                     const void *in,int count); 
     32typedef void ops_decrypt_finish_t(ops_decrypt_t *decrypt); 
     33 
     34struct _ops_decrypt_t 
     35    { 
     36    ops_symmetric_algorithm_t algorithm; 
     37    ops_decrypt_init_t *init; 
     38    ops_decrypt_decrypt_t *decrypt; 
     39    ops_decrypt_finish_t *finish; 
    2540    void *data; 
    2641    }; 
     
    4863unsigned ops_block_size(ops_symmetric_algorithm_t alg); 
    4964 
     65int ops_decrypt_data(ops_region_t *region,ops_parse_info_t *parse_info); 
     66 
     67void ops_decrypt_any(ops_decrypt_t *decrypt, 
     68                     ops_symmetric_algorithm_t algorithm); 
     69 
    5070#endif 
  • openpgpsdk/trunk/include/openpgpsdk/errors.h

    r332 r336  
    2727    /* parser errors */ 
    2828    OPS_E_P=0x3000,     /* general parser error */ 
    29     OPS_E_P_NOT_ENOUGH_DATA=OPS_E_P+1, 
     29    OPS_E_P_NOT_ENOUGH_DATA     =OPS_E_P+1, 
     30    OPS_E_P_UNKNOWN_TAG         =OPS_E_P+2, 
     31    OPS_E_P_PACKET_CONSUMED     =OPS_E_P+3, 
     32    OPS_E_P_MPI_FORMAT_ERROR    =OPS_E_P+4, 
    3033 
    3134    /* creator errors */ 
  • openpgpsdk/trunk/include/openpgpsdk/keyring.h

    r241 r336  
    2828const ops_public_key_t * 
    2929ops_get_public_key_from_data(const ops_key_data_t *data); 
     30ops_boolean_t ops_key_is_secret(const ops_key_data_t *data); 
     31const ops_secret_key_t * 
     32ops_get_secret_key_from_data(const ops_key_data_t *data); 
     33ops_secret_key_t *ops_decrypt_secret_key_from_data(ops_key_data_t *key, 
     34                                                   const char *pphrase); 
     35 
     36void ops_keyring_read(ops_keyring_t *keyring,const char *file); 
     37 
     38char *ops_get_passphrase(void); 
    3039 
    3140#endif 
  • openpgpsdk/trunk/include/openpgpsdk/packet-parse.h

    r335 r336  
    6565void ops_parse_info_delete(ops_parse_info_t *pinfo); 
    6666ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo); 
     67ops_decrypt_t *ops_parse_get_decrypt(ops_parse_info_t *pinfo); 
    6768 
    6869void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 
    6970void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 
     71void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo); 
    7072void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 
    7173void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 
     74void *ops_reader_get_arg_from_pinfo(ops_parse_info_t *pinfo); 
    7275 
    7376void *ops_reader_get_arg(ops_reader_info_t *rinfo); 
    74 void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo); 
    7577 
    7678ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, 
  • openpgpsdk/trunk/include/openpgpsdk/packet.h

    r335 r336  
    128128    OPS_PTAG_CT_SECRET_SUBKEY           = 7,    /*!< Secret Subkey Packet */ 
    129129    OPS_PTAG_CT_COMPRESSED              = 8,    /*!< Compressed Data Packet */ 
    130     OPS_PTAG_CT_SK_DATA                       = 9,    /*!< Symmetrically Encrypted Data Packet */ 
     130    OPS_PTAG_CT_SE_DATA                       = 9,    /*!< Symmetrically Encrypted Data Packet */ 
    131131    OPS_PTAG_CT_MARKER                  =10,    /*!< Marker Packet */ 
    132132    OPS_PTAG_CT_LITERAL_DATA            =11,    /*!< Literal Data Packet */ 
     
    198198    OPS_PTAG_CT_UNARMOURED_TEXT         =0x300+9, 
    199199    OPS_PTAG_CT_ENCRYPTED_SECRET_KEY    =0x300+10, // In this case the algorithm specific fields will not be initialised 
     200    OPS_PTAG_CT_SE_DATA_HEADER          =0x300+11, 
     201    OPS_PTAG_CT_SE_DATA_BODY            =0x300+12, 
    200202 
    201203    /* commands to the callback */ 
    202     OPS_PTAG_CMD_GET_PASSPHRASE               =0x400, 
     204    OPS_PARSER_CMD_GET_PASSPHRASE     =0x400, 
    203205 
    204206 
     
    206208    OPS_PARSER_ERROR                    =0x500, /*!< Internal Use: Parser Error */ 
    207209    OPS_PARSER_ERRCODE                  =0x500+1, /*! < Internal Use: Parser Error with errcode returned */ 
    208     OPS_PARSER_ERROR_UNKNOWN_TAG        =0x500+2, 
    209     OPS_PARSER_ERROR_PACKET_CONSUMED    =0x500+3, 
    210210    }; 
    211211 
     
    315315typedef enum 
    316316    { 
     317    OPS_V2=2,   /*<! Version 2 (essentially the same as v3) */ 
    317318    OPS_V3=3,   /*<! Version 3 */ 
    318319    OPS_V4=4,   /*<! Version 4 */ 
     
    394395    } ops_symmetric_algorithm_t; 
    395396 
     397/** Hashing Algorithm Numbers. 
     398 * OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP. 
     399 *  
     400 * This lists algorithm numbers for hash algorithms. 
     401 * 
     402 * \see RFC2440bis-12 9.4 
     403 */ 
     404typedef enum 
     405    { 
     406    OPS_HASH_UNKNOWN    =-1,    /*!< used to indicate errors */ 
     407    OPS_HASH_MD5        = 1,    /*!< MD5 */ 
     408    OPS_HASH_SHA1       = 2,    /*!< SHA-1 */ 
     409    OPS_HASH_RIPEMD     = 3,    /*!< RIPEMD160 */ 
     410 
     411    OPS_HASH_SHA256     = 8,    /*!< SHA256 */ 
     412    OPS_HASH_SHA384     = 9,    /*!< SHA384 */ 
     413    OPS_HASH_SHA512     =10,    /*!< SHA512 */ 
     414    } ops_hash_algorithm_t; 
     415 
    396416// Maximum block size for symmetric crypto 
    397417#define OPS_MAX_BLOCK_SIZE      16 
     418 
     419// Salt size for hashing 
     420#define OPS_SALT_SIZE           8 
    398421 
    399422/** ops_secret_key_t 
     
    405428    ops_s2k_specifier_t         s2k_specifier; 
    406429    ops_symmetric_algorithm_t   algorithm; 
     430    ops_hash_algorithm_t        hash_algorithm; 
     431    unsigned char               salt[OPS_SALT_SIZE]; 
     432    unsigned char               iterations; 
    407433    unsigned char               iv[OPS_MAX_BLOCK_SIZE]; 
    408434    unsigned                    checksum; 
     
    462488    OPS_SIG_3RD_PARTY   =0x50,  /*<! Third-Party Confirmation signature */ 
    463489    } ops_sig_type_t; 
    464  
    465 /** Hashing Algorithm Numbers. 
    466  * OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP. 
    467  *  
    468  * This lists algorithm numbers for hash algorithms. 
    469  * 
    470  * \see RFC2440bis-12 9.4 
    471  */ 
    472 typedef enum 
    473     { 
    474     OPS_HASH_UNKNOWN    =-1,    /*!< used to indicate errors */ 
    475     OPS_HASH_MD5        = 1,    /*!< MD5 */ 
    476     OPS_HASH_SHA1       = 2,    /*!< SHA-1 */ 
    477     OPS_HASH_RIPEMD     = 3,    /*!< RIPEMD160 */ 
    478  
    479     OPS_HASH_SHA256     = 8,    /*!< SHA256 */ 
    480     OPS_HASH_SHA384     = 9,    /*!< SHA384 */ 
    481     OPS_HASH_SHA512     =10,    /*!< SHA512 */ 
    482     } ops_hash_algorithm_t; 
    483490 
    484491/** Struct to hold parameters of an RSA signature */ 
  • openpgpsdk/trunk/include/openpgpsdk/types.h

    r307 r336  
    2424/** ops_content_tag_t */ 
    2525typedef enum ops_content_tag_t ops_content_tag_t; 
     26 
     27typedef struct _ops_decrypt_t ops_decrypt_t; 
    2628 
    2729/** ops_hash_t */ 
  • openpgpsdk/trunk/include/openpgpsdk/validate.h

    r241 r336  
    11void ops_validate_all_signatures(const ops_keyring_t *ring); 
     2void ops_key_data_reader_set(ops_parse_info_t *pinfo, 
     3                             const ops_key_data_t *key); 
  • openpgpsdk/trunk/src/accumulate.c

    r335 r336  
    2828    ops_keyring_t *keyring=arg->keyring; 
    2929    ops_key_data_t *cur=&keyring->keys[keyring->nkeys]; 
     30    const ops_public_key_t *pkey; 
    3031 
    3132    switch(content_->tag) 
     
    3839        EXPAND_ARRAY(keyring,keys); 
    3940 
     41        if(content_->tag == OPS_PTAG_CT_PUBLIC_KEY) 
     42            pkey=&content->public_key; 
     43        else 
     44            pkey=&content->secret_key.public_key; 
     45 
    4046        memset(&keyring->keys[keyring->nkeys],'\0', 
    4147               sizeof keyring->keys[keyring->nkeys]); 
    4248 
    43         ops_keyid(keyring->keys[keyring->nkeys].keyid,&content->public_key); 
    44         ops_fingerprint(&keyring->keys[keyring->nkeys].fingerprint, 
    45                         &content->public_key); 
     49        ops_keyid(keyring->keys[keyring->nkeys].keyid,pkey); 
     50        ops_fingerprint(&keyring->keys[keyring->nkeys].fingerprint,pkey); 
    4651 
    47         keyring->keys[keyring->nkeys].pkey=content->public_key; 
     52        keyring->keys[keyring->nkeys].type=content_->tag; 
     53 
     54        if(content_->tag == OPS_PTAG_CT_PUBLIC_KEY) 
     55            keyring->keys[keyring->nkeys].key.pkey=*pkey; 
     56        else 
     57            keyring->keys[keyring->nkeys].key.skey=content->secret_key; 
    4858        return OPS_KEEP_MEMORY; 
    4959 
  • openpgpsdk/trunk/src/compress.c

    r320 r336  
    119119    memset(&arg,'\0',sizeof arg); 
    120120 
    121  
    122121    arg.region=region; 
    123122 
  • openpgpsdk/trunk/src/errors.c

    r320 r336  
    1111 
    1212#include "openpgpsdk/util.h" 
     13 
     14#define ERR(code)       { code, #code } 
    1315 
    1416static ops_errcode_name_map_t errcode_name_map[] =  
     
    2830    { OPS_E_P,  "OPS_E_P" }, 
    2931    { OPS_E_P_NOT_ENOUGH_DATA, "OPS_E_P_NOT_ENOUGH_DATA" }, 
     32    { OPS_E_P_UNKNOWN_TAG,"OPS_E_P_UNKNOWN_TAG" }, 
     33    { OPS_E_P_PACKET_CONSUMED,"OPS_E_P_PACKET_CONSUMED" }, 
     34    ERR(OPS_E_P_MPI_FORMAT_ERROR), 
    3035 
    3136    { OPS_E_C,  "OPS_E_C" }, 
  • openpgpsdk/trunk/src/keyring.c

    r250 r336  
    33 
    44#include <openpgpsdk/keyring.h> 
     5#include <openpgpsdk/packet-parse.h> 
     6#include <openpgpsdk/util.h> 
     7#include <openpgpsdk/accumulate.h> 
     8#include <openpgpsdk/validate.h> 
    59#include "keyring_local.h" 
    610#include <stdlib.h> 
    711#include <string.h> 
     12#include <unistd.h> 
     13#include <fcntl.h> 
     14#include <assert.h> 
    815 
    916ops_key_data_t * 
     
    3441    key->packets=NULL; 
    3542 
    36     ops_public_key_free(&key->pkey); 
     43    if(key->type == OPS_PTAG_CT_PUBLIC_KEY) 
     44        ops_public_key_free(&key->key.pkey); 
     45    else 
     46        ops_secret_key_free(&key->key.skey); 
    3747    } 
    3848 
     
    5565const ops_public_key_t * 
    5666ops_get_public_key_from_data(const ops_key_data_t *data) 
    57     { return &data->pkey; } 
    58  
    59  
     67    { 
     68    if(data->type == OPS_PTAG_CT_PUBLIC_KEY) 
     69        return &data->key.pkey; 
     70    return &data->key.skey.public_key; 
     71    } 
     72 
     73ops_boolean_t ops_key_is_secret(const ops_key_data_t *data) 
     74    { return data->type != OPS_PTAG_CT_PUBLIC_KEY; } 
     75 
     76const ops_secret_key_t * 
     77ops_get_secret_key_from_data(const ops_key_data_t *data) 
     78    { 
     79    if(data->type != OPS_PTAG_CT_SECRET_KEY) 
     80        return NULL; 
     81    return &data->key.skey; 
     82    } 
     83 
     84static ops_parse_cb_return_t 
     85cb_keyring_read(const ops_parser_content_t *content_, 
     86                ops_parse_cb_info_t *cbinfo) 
     87    { 
     88    //    const ops_parser_content_union_t *content=&content_->content; 
     89    //    char buffer[1024]; 
     90    //    size_t n; 
     91 
     92    OPS_USED(cbinfo); 
     93 
     94    switch(content_->tag) 
     95        { 
     96    case OPS_PARSER_PTAG: 
     97    case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: // we get these because we didn't prompt 
     98    case OPS_PTAG_CT_SIGNATURE_HEADER: 
     99    case OPS_PTAG_CT_SIGNATURE_FOOTER: 
     100    case OPS_PTAG_CT_SIGNATURE: 
     101    case OPS_PTAG_CT_TRUST: 
     102    case OPS_PARSER_ERRCODE: 
     103        break; 
     104 
     105    case OPS_PARSER_CMD_GET_PASSPHRASE: 
     106        // we don't want to prompt when reading the keyring 
     107        break; 
     108 
     109    default: 
     110        fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag, 
     111                content_->tag); 
     112        assert(0); 
     113        exit(1); 
     114        } 
     115 
     116    return OPS_RELEASE_MEMORY; 
     117    } 
     118 
     119/* Read a keyring from a file (either public or secret) */ 
     120void ops_keyring_read(ops_keyring_t *keyring,const char *file) 
     121    { 
     122    ops_parse_info_t *pinfo; 
     123    int fd; 
     124 
     125    memset(keyring,'\0',sizeof *keyring); 
     126 
     127    pinfo=ops_parse_info_new(); 
     128 
     129    fd=open(file,O_RDONLY); 
     130    if(fd < 0) 
     131        { 
     132        perror(file); 
     133        exit(1); 
     134        } 
     135 
     136    ops_reader_set_fd(pinfo,fd); 
     137 
     138    ops_parse_cb_set(pinfo,cb_keyring_read,NULL); 
     139 
     140    ops_parse_and_accumulate(keyring,pinfo); 
     141 
     142    close(fd); 
     143 
     144    ops_parse_info_delete(pinfo); 
     145    } 
     146 
     147char *ops_get_passphrase(void) 
     148    { 
     149    char buffer[1024]; 
     150    char *passphrase; 
     151    size_t n; 
     152 
     153    printf("Passphrase: "); 
     154    fgets(buffer,sizeof buffer,stdin); 
     155    n=strlen(buffer); 
     156    if(n && buffer[n-1] == '\n') 
     157        buffer[--n]='\0'; 
     158    passphrase=malloc(n+1); 
     159    strcpy(passphrase,buffer); 
     160 
     161    return passphrase; 
     162    } 
     163 
     164typedef struct 
     165    { 
     166    ops_key_data_t *key; 
     167    char *pphrase; 
     168    ops_secret_key_t *skey; 
     169    } decrypt_arg_t; 
     170 
     171static ops_parse_cb_return_t decrypt_cb(const ops_parser_content_t *content_, 
     172                                        ops_parse_cb_info_t *cbinfo) 
     173    { 
     174    const ops_parser_content_union_t *content=&content_->content; 
     175    decrypt_arg_t *arg=ops_parse_cb_get_arg(cbinfo); 
     176 
     177    OPS_USED(cbinfo); 
     178 
     179    switch(content_->tag) 
     180        { 
     181    case OPS_PARSER_PTAG: 
     182    case OPS_PTAG_CT_USER_ID: 
     183    case OPS_PTAG_CT_SIGNATURE: 
     184    case OPS_PTAG_CT_TRUST: 
     185        break; 
     186 
     187    case OPS_PARSER_CMD_GET_PASSPHRASE: 
     188        *content->passphrase=arg->pphrase; 
     189        return OPS_KEEP_MEMORY; 
     190 
     191    case OPS_PARSER_ERRCODE: 
     192        switch(content->errcode.errcode) 
     193            { 
     194        case OPS_E_P_MPI_FORMAT_ERROR: 
     195            /* Generally this means a bad passphrase */ 
     196            fprintf(stderr,"Bad passphrase!\n"); 
     197            goto done; 
     198 
     199        case OPS_E_P_PACKET_CONSUMED: 
     200            /* And this is because of an error we've accepted */ 
     201            goto done; 
     202 
     203        default: 
     204            fprintf(stderr,"parse error: %s\n", 
     205                    ops_errcode(content->errcode.errcode)); 
     206            assert(0); 
     207            break; 
     208            } 
     209 
     210        break; 
     211 
     212    case OPS_PARSER_ERROR: 
     213        printf("parse error: %s\n",content->error.error); 
     214        assert(0); 
     215        break; 
     216 
     217    default: 
     218        fprintf(stderr,"Unexpected tag %d (0x%x)\n",content_->tag, 
     219                content_->tag); 
     220        assert(0); 
     221        } 
     222 
     223 done: 
     224    return OPS_RELEASE_MEMORY; 
     225    } 
     226 
     227ops_secret_key_t *ops_decrypt_secret_key_from_data(ops_key_data_t *key, 
     228                                                   const char *pphrase) 
     229    { 
     230    ops_parse_info_t *pinfo; 
     231    decrypt_arg_t arg; 
     232 
     233    memset(&arg,'\0',sizeof arg); 
     234    arg.key=key; 
     235    arg.pphrase=strdup(pphrase); 
     236 
     237    pinfo=ops_parse_info_new(); 
     238 
     239    ops_key_data_reader_set(pinfo,key); 
     240    ops_parse_cb_set(pinfo,decrypt_cb,&arg); 
     241 
     242    ops_parse(pinfo); 
     243 
     244    return arg.skey; 
     245    } 
     246 
  • openpgpsdk/trunk/src/keyring_local.h

    r241 r336  
    99                                } while(0) 
    1010 
     11typedef union 
     12    { 
     13    ops_public_key_t pkey; 
     14    ops_secret_key_t skey; 
     15    } ops_key_data_key_t; 
     16     
     17 
    1118// XXX: gonna have to expand this to hold onto subkeys, too... 
    1219struct ops_key_data 
     
    1522    DECLARE_ARRAY(ops_packet_t,packets); 
    1623    unsigned char keyid[8]; 
    17     ops_public_key_t pkey; 
    1824    ops_fingerprint_t fingerprint; 
     25    ops_content_tag_t type; 
     26    ops_key_data_key_t key; 
    1927    }; 
  • openpgpsdk/trunk/src/packet-parse.c

    r335 r336  
    113113/*! set error code in content and run CallBack to handle error */ 
    114114#define ERRCODE(cbinfo,err)     do { C.errcode.errcode=err; CB(cbinfo,OPS_PARSER_ERRCODE,&content); } while(0) 
     115#define ERRCODEP(pinfo,err)     do { C.errcode.errcode=err; CBP(pinfo,OPS_PARSER_ERRCODE,&content); } while(0) 
    115116/*! set error text in content and run CallBack to handle error, then return */ 
    116117#define ERR(cbinfo,err) do { C.error.error=err; CB(cbinfo,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 
     
    119120#define WARN(warn)      do { C.error.error=warn; CB(OPS_PARSER_ERROR,&content);; } while(0) 
    120121#define WARNP(info,warn)        do { C.error.error=warn; CBP(info,OPS_PARSER_ERROR,&content); } while(0) 
    121 #define SWARNP(errtype,info,warn)       do { C.error.error=warn; CBP(info,errtype,&content); } while(0) 
    122122/*! \todo descr ERR1 macro */ 
    123123#define ERR1P(info,fmt,x)       do { format_error(&content,(fmt),(x)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 
     
    476476 
    477477    if((buf[0] >> nonzero) != 0 || !(buf[0]&(1 << (nonzero-1)))) 
    478         ERRP(parse_info,"MPI format error");  /* XXX: Ben, one part of this constraint does not apply to encrypted MPIs the draft says. -- peter */ 
     478        { 
     479        ERRCODEP(parse_info,OPS_E_P_MPI_FORMAT_ERROR);  /* XXX: Ben, one part of this constraint does not apply to encrypted MPIs the draft says. -- peter */ 
     480        return 0; 
     481        } 
    479482 
    480483    *pbn=BN_bin2bn(buf,length,NULL); 
     
    624627    case OPS_PTAG_CT_ARMOUR_TRAILER: 
    625628    case OPS_PTAG_CT_SIGNATURE_HEADER: 
     629    case OPS_PTAG_CT_SE_DATA: 
    626630        break; 
    627631 
     
    732736    case OPS_PARSER_ERROR: 
    733737    case OPS_PARSER_ERRCODE: 
    734     case OPS_PARSER_ERROR_UNKNOWN_TAG: 
    735     case OPS_PARSER_ERROR_PACKET_CONSUMED: 
    736738        break; 
    737739 
     
    745747        break; 
    746748 
    747     case OPS_PTAG_CMD_GET_PASSPHRASE: 
     749    case OPS_PARSER_CMD_GET_PASSPHRASE: 
    748750        ops_cmd_get_passphrase_free(c->content.passphrase); 
    749751        break; 
     
    17731775        data_free(&remainder); 
    17741776        if(warn) 
    1775             SWARNP(OPS_PARSER_ERROR_PACKET_CONSUMED,parse_info, 
    1776                    "Remainder of packet consumed and discarded."); 
     1777            ERRCODEP(parse_info,OPS_E_P_PACKET_CONSUMED); 
    17771778        } 
    17781779    else if(warn) 
     
    18061807            return 0; 
    18071808        C.secret_key.s2k_specifier=c[0]; 
     1809 
     1810        assert(C.secret_key.s2k_specifier == OPS_S2KS_SIMPLE 
     1811               || C.secret_key.s2k_specifier == OPS_S2KS_SALTED 
     1812               || C.secret_key.s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED); 
     1813 
     1814        if(!limited_read(c,1,region,parse_info)) 
     1815            return 0; 
     1816        C.secret_key.hash_algorithm=c[0]; 
     1817 
     1818        if(C.secret_key.s2k_specifier != OPS_S2KS_SIMPLE 
     1819           && !limited_read(C.secret_key.salt,8,region,parse_info)) 
     1820            return 0; 
     1821 
     1822        if(C.secret_key.s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED) 
     1823            { 
     1824            if(!limited_read(c,1,region,parse_info)) 
     1825                return 0; 
     1826            C.secret_key.iterations=c[0]; 
     1827            } 
    18081828        } 
    18091829    else if(C.secret_key.s2k_usage != OPS_S2KU_NONE) 
    18101830        { 
     1831        // this is V3 style, looks just like a V4 simple hash 
    18111832        C.secret_key.algorithm=C.secret_key.s2k_usage; 
    1812         C.secret_key.s2k_usage=OPS_S2KU_NOT_SET; 
    1813         } 
    1814  
    1815     if(C.secret_key.s2k_usage != OPS_S2KU_NONE) 
     1833        C.secret_key.s2k_usage=OPS_S2KU_ENCRYPTED; 
     1834        C.secret_key.s2k_specifier=OPS_S2KS_SIMPLE; 
     1835        } 
     1836 
     1837    if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED 
     1838       || C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) 
    18161839        { 
    18171840        int n; 
     
    18271850        passphrase=NULL; 
    18281851        pc.content.passphrase=&passphrase; 
    1829         CBP(parse_info,OPS_PTAG_CMD_GET_PASSPHRASE,&pc); 
     1852        CBP(parse_info,OPS_PARSER_CMD_GET_PASSPHRASE,&pc); 
    18301853        if(!passphrase) 
    18311854            { 
     
    19111934 
    19121935    return 1; 
     1936    } 
     1937 
     1938static int parse_se_data(ops_region_t *region,ops_parse_info_t *parse_info) 
     1939    { 
     1940    ops_parser_content_t content; 
     1941 
     1942    /* there's no info to go with this, so just announce it */ 
     1943    CBP(parse_info,OPS_PTAG_CT_SE_DATA,&content); 
     1944 
     1945    /* The content of an encrypted data packet is more OpenPGP packets 
     1946       once decompressed, so recursively handle them */ 
     1947    return ops_decrypt_data(region,parse_info); 
    19131948    } 
    19141949 
     
    20342069        break; 
    20352070 
     2071    case OPS_PTAG_CT_SE_DATA: 
     2072        r=parse_se_data(&region,parse_info); 
     2073        break; 
     2074 
    20362075    default: 
    20372076        format_error(&content,"Format error (unknown content tag %d)", 
    20382077                     C.ptag.content_tag); 
    2039         CBP(parse_info,OPS_PARSER_ERROR_UNKNOWN_TAG,&content); 
     2078        ERRCODEP(parse_info,OPS_E_P_UNKNOWN_TAG); 
    20402079        r=0; 
    20412080        } 
     
    22432282                                   ops_parse_cb_info_t *cbinfo) 
    22442283    {  
    2245     if (cbinfo->cb) 
     2284    if(cbinfo->cb) 
    22462285        return cbinfo->cb(content,cbinfo);  
    22472286    else 
     
    22712310    { return rinfo->arg; } 
    22722311 
     2312void *ops_reader_get_arg_from_pinfo(ops_parse_info_t *pinfo) 
     2313    { return pinfo->rinfo.arg; } 
     2314 
    22732315ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo) 
    22742316    { return pinfo->errors; } 
    22752317 
     2318ops_decrypt_t *ops_parse_get_decrypt(ops_parse_info_t *pinfo) 
     2319    { return pinfo->decrypt; } 
     2320 
    22762321/* vim:set textwidth=120: */ 
    22772322/* vim:set ts=8: */ 
  • openpgpsdk/trunk/src/packet-show.c

    r333 r336  
    2828    { OPS_PTAG_CT_SECRET_SUBKEY,                "Secret Subkey" }, 
    2929    { OPS_PTAG_CT_COMPRESSED,           "Compressed Data" }, 
    30     { OPS_PTAG_CT_SK_DATA,            "Symmetrically Encrypted Data" }, 
     30    { OPS_PTAG_CT_SE_DATA,            "Symmetrically Encrypted Data" }, 
    3131    { OPS_PTAG_CT_MARKER,               "Marker" }, 
    3232    { OPS_PTAG_CT_LITERAL_DATA,         "Literal Data" }, 
  • openpgpsdk/trunk/src/parse_local.h

    r334 r336  
    5757    ops_parse_cb_info_t cbinfo; 
    5858    ops_error_t *errors; 
     59    ops_decrypt_t *decrypt; 
    5960    }; 
  • openpgpsdk/trunk/src/validate.c

    r320 r336  
    44#include <openpgpsdk/util.h> 
    55#include <openpgpsdk/signature.h> 
     6#include <openpgpsdk/validate.h> 
    67#include <assert.h> 
    78#include <string.h> 
     
    5859static ops_parse_cb_return_t 
    5960validate_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 
    60    
    61     const ops_parser_content_union_t *content=&content_->content; 
    62     validate_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); 
    63     const ops_key_data_t *signer; 
    64     ops_boolean_t valid; 
     61   
     62    const ops_parser_content_union_t *content=&content_->content; 
     63    validate_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); 
     64    const ops_key_data_t *signer; 
     65    ops_boolean_t valid; 
    6566 
    66     switch(content_->tag) 
    67        
    68     case OPS_PTAG_CT_PUBLIC_KEY: 
    69         assert(arg->pkey.version == 0); 
    70         arg->pkey=content->public_key; 
    71         return OPS_KEEP_MEMORY; 
     67    switch(content_->tag) 
     68       
     69    case OPS_PTAG_CT_PUBLIC_KEY: 
     70        assert(arg->pkey.version == 0); 
     71        arg->pkey=content->public_key; 
     72        return OPS_KEEP_MEMORY; 
    7273 
    73     case OPS_PTAG_CT_PUBLIC_SUBKEY: 
    74         if(arg->subkey.version) 
    75             ops_public_key_free(&arg->subkey); 
    76         arg->subkey=content->public_key; 
    77         return OPS_KEEP_MEMORY; 
     74    case OPS_PTAG_CT_PUBLIC_SUBKEY: 
     75        if(arg->subkey.version) 
     76            ops_public_key_free(&arg->subkey); 
     77        arg->subkey=content->public_key; 
     78        return OPS_KEEP_MEMORY; 
    7879 
    79     case OPS_PTAG_CT_USER_ID: 
    80         printf("user id=%s\n",content->user_id.user_id); 
    81         if(arg->user_id.user_id) 
    82             ops_user_id_free(&arg->user_id); 
    83         arg->user_id=content->user_id; 
    84         return OPS_KEEP_MEMORY; 
     80    case OPS_PTAG_CT_USER_ID: 
     81        printf("user id=%s\n",content->user_id.user_id); 
     82        if(arg->user_id.user_id) 
     83            ops_user_id_free(&arg->user_id); 
     84        arg->user_id=content->user_id; 
     85        return OPS_KEEP_MEMORY; 
    8586 
    86     case OPS_PTAG_CT_SIGNATURE_FOOTER: 
    87         printf("  type=%02x signer_id=",content->signature.type); 
    88         hexdump(content->signature.signer_id, 
    89                 sizeof content->signature.signer_id); 
     87    case OPS_PTAG_CT_SIGNATURE_FOOTER: 
     88        printf("  type=%02x signer_id=",content->signature.type); 
     89        hexdump(content->signature.signer_id, 
     90                sizeof content->signature.signer_id); 
    9091 
    91         signer=ops_keyring_find_key_by_id(arg->keyring, 
     92        signer=ops_keyring_find_key_by_id(arg->keyring, 
    9293                                           content->signature.signer_id); 
    93         if(!signer) 
    94            
    95             printf(" UNKNOWN SIGNER\n"); 
    96             break; 
    97            
     94        if(!signer) 
     95           
     96            printf(" UNKNOWN SIGNER\n"); 
     97            break; 
     98           
    9899 
    99         switch(content->signature.type) 
    100            
    101         case OPS_CERT_GENERIC: 
    102         case OPS_CERT_PERSONA: 
    103         case OPS_CERT_CASUAL: 
    104         case OPS_CERT_POSITIVE: 
    105         case OPS_SIG_REV_CERT: 
    106             valid=ops_check_certification_signature(&arg->pkey,&arg->user_id, 
    107                     &content->signature,&signer->pkey
    108                     arg->rarg->key->packets[arg->rarg->packet].raw); 
    109             break; 
     100        switch(content->signature.type) 
     101           
     102        case OPS_CERT_GENERIC: 
     103        case OPS_CERT_PERSONA: 
     104        case OPS_CERT_CASUAL: 
     105        case OPS_CERT_POSITIVE: 
     106        case OPS_SIG_REV_CERT: 
     107            valid=ops_check_certification_signature(&arg->pkey,&arg->user_id, 
     108                    &content->signature,ops_get_public_key_from_data(signer)
     109                    arg->rarg->key->packets[arg->rarg->packet].raw); 
     110            break; 
    110111 
    111          case OPS_SIG_SUBKEY: 
    112              // XXX: we should also check that the signer is the key we are validating, I think. 
    113              valid=ops_check_subkey_signature(&arg->pkey,&arg->subkey, 
    114                      &content->signature,&signer->pkey, 
    115                      arg->rarg->key->packets[arg->rarg->packet].raw); 
    116              break; 
     112        case OPS_SIG_SUBKEY: 
     113            // XXX: we should also check that the signer is the key we are validating, I think. 
     114            valid=ops_check_subkey_signature(&arg->pkey,&arg->subkey, 
     115                    &content->signature, 
     116                    ops_get_public_key_from_data(signer), 
     117                    arg->rarg->key->packets[arg->rarg->packet].raw); 
     118            break; 
    117119 
    118         default: 
    119             fprintf(stderr,"Unexpected signature type=0x%02x\n", 
    120                     content->signature.type); 
    121             exit(1); 
    122            
    123         if(valid) 
    124             printf(" validated\n"); 
    125         else 
    126             printf(" BAD SIGNATURE\n"); 
    127         break; 
     120        default: 
     121            fprintf(stderr,"Unexpected signature type=0x%02x\n", 
     122                    content->signature.type); 
     123            exit(1); 
     124           
     125        if(valid) 
     126            printf(" validated\n"); 
     127        else 
     128            printf(" BAD SIGNATURE\n"); 
     129        break; 
    128130 
    129      default: 
    130          // XXX: reinstate when we can make packets optional 
    131          //     fprintf(stderr,"unexpected tag=%d\n",content_->tag); 
    132          break; 
    133          } 
    134      return OPS_RELEASE_MEMORY; 
    135      } 
     131    default: 
     132        // XXX: reinstate when we can make packets optional 
     133        //      fprintf(stderr,"unexpected tag=%d\n",content_->tag); 
     134        break; 
     135        } 
     136    return OPS_RELEASE_MEMORY; 
     137    } 
     138 
     139void ops_key_data_reader_set(ops_parse_info_t *pinfo,const ops_key_data_t *key) 
     140    { 
     141    validate_reader_arg_t *arg=malloc(sizeof *arg); 
     142 
     143    memset(arg,'\0',sizeof *arg); 
     144 
     145    arg->key=key; 
     146    arg->packet=0; 
     147    arg->offset=0; 
     148 
     149    ops_reader_set(pinfo,key_data_reader,arg); 
     150    } 
    136151 
    137152static void validate_key_signatures(const ops_key_data_t *key, 
     
    140155    ops_parse_info_t *pinfo; 
    141156    validate_cb_arg_t carg; 
    142     validate_reader_arg_t rarg; 
    143157 
    144     memset(&rarg,'\0',sizeof rarg); 
    145158    memset(&carg,'\0',sizeof carg); 
    146159 
     
    148161    //    ops_parse_options(&opt,OPS_PTAG_CT_SIGNATURE,OPS_PARSE_PARSED); 
    149162 
    150     rarg.key=key; 
    151     rarg.packet=0; 
    152     rarg.offset=0; 
    153  
    154163    carg.keyring=keyring; 
    155     carg.rarg=&rarg; 
    156164 
    157165    ops_parse_cb_set(pinfo,validate_cb,&carg); 
    158     ops_reader_set(pinfo,key_data_reader,&rarg); 
     166    ops_key_data_reader_set(pinfo,key); 
     167 
     168    carg.rarg=ops_reader_get_arg_from_pinfo(pinfo); 
    159169 
    160170    ops_parse(pinfo);