Changeset 336
- Timestamp:
- 01/25/06 18:40:09
- Files:
-
- openpgpsdk/trunk/examples/decrypt.c (modified) (2 diffs)
- openpgpsdk/trunk/examples/packet-dump.c (modified) (12 diffs)
- openpgpsdk/trunk/include/openpgpsdk/crypto.h (modified) (3 diffs)
- openpgpsdk/trunk/include/openpgpsdk/errors.h (modified) (1 diff)
- openpgpsdk/trunk/include/openpgpsdk/keyring.h (modified) (1 diff)
- openpgpsdk/trunk/include/openpgpsdk/packet-parse.h (modified) (1 diff)
- openpgpsdk/trunk/include/openpgpsdk/packet.h (modified) (7 diffs)
- openpgpsdk/trunk/include/openpgpsdk/types.h (modified) (1 diff)
- openpgpsdk/trunk/include/openpgpsdk/validate.h (modified) (1 diff)
- openpgpsdk/trunk/src/accumulate.c (modified) (2 diffs)
- openpgpsdk/trunk/src/compress.c (modified) (1 diff)
- openpgpsdk/trunk/src/errors.c (modified) (2 diffs)
- openpgpsdk/trunk/src/keyring.c (modified) (3 diffs)
- openpgpsdk/trunk/src/keyring_local.h (modified) (2 diffs)
- openpgpsdk/trunk/src/packet-parse.c (modified) (13 diffs)
- openpgpsdk/trunk/src/packet-show.c (modified) (1 diff)
- openpgpsdk/trunk/src/parse_local.h (modified) (1 diff)
- openpgpsdk/trunk/src/validate.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
openpgpsdk/trunk/examples/decrypt.c
r335 r336 14 14 15 15 static ops_parse_cb_return_t 16 c b_secret_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)16 callback(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) 17 17 { 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; 21 21 22 22 OPS_USED(cbinfo); 23 23 24 switch(content_->tag)24 if(content_->tag != OPS_PTAG_CT_UNARMOURED_TEXT && skipping) 25 25 { 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; 55 28 } 56 57 return OPS_RELEASE_MEMORY;58 }59 60 static ops_parse_cb_return_t61 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);65 29 66 30 switch(content_->tag) 67 31 { 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 68 56 default: 69 57 fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag, … … 108 96 ops_init(); 109 97 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); 128 99 129 100 pinfo=ops_parse_info_new(); openpgpsdk/trunk/examples/packet-dump.c
r335 r336 7 7 #include <openpgpsdk/armour.h> 8 8 #include <openpgpsdk/crypto.h> 9 #include <openpgpsdk/keyring.h> 9 10 10 11 #include <unistd.h> … … 17 18 static int indent=0; 18 19 static const char *pname; 20 static ops_keyring_t keyring; 19 21 20 22 static void print_indent() … … 166 168 } 167 169 170 static 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 168 182 static void print_string(const char *name,const char *str) 169 183 { 170 184 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)); 179 186 putchar('\n'); 180 187 } … … 323 330 ops_text_t *text; 324 331 char *str; 332 ops_key_data_t *decrypter; 333 const ops_secret_key_t *secret; 334 static ops_boolean_t unarmoured; 325 335 326 336 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 } 327 343 328 344 switch(content_->tag) … … 342 358 343 359 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) 346 361 { 347 362 indent=0; … … 359 374 print_tagname(ops_str_from_single_packet_tag(content->ptag.content_tag)); 360 375 */ 376 break; 377 378 case OPS_PTAG_CT_SE_DATA: 379 print_tagname("SYMMETRIC ENCRYPTED DATA"); 361 380 break; 362 381 … … 783 802 break; 784 803 785 case OPS_P TAG_CMD_GET_PASSPHRASE:804 case OPS_PARSER_CMD_GET_PASSPHRASE: 786 805 printf(">>> ASKED FOR PASSPHRASE <<<\n"); 787 806 break; … … 838 857 839 858 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(']'); 843 868 break; 844 869 … … 871 896 assert(0); 872 897 } 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 873 917 break; 874 918 … … 900 944 ops_boolean_t buffer_read=ops_false; 901 945 unsigned char buffer[10240]; 946 const char *keyring_file=NULL; 902 947 903 948 pname=argv[0]; 904 949 905 while((ch=getopt(argc,argv,"abB ")) != -1)950 while((ch=getopt(argc,argv,"abBk:")) != -1) 906 951 switch(ch) 907 952 { … … 917 962 case 'B': 918 963 buffer_read=ops_true; 964 break; 965 966 case 'k': 967 keyring_file=optarg; 919 968 break; 920 969 … … 927 976 if(argc != 1) 928 977 usage(); 978 979 if(keyring_file) 980 ops_keyring_read(&keyring,keyring_file); 929 981 930 982 fd=open(argv[0],O_RDONLY); openpgpsdk/trunk/include/openpgpsdk/crypto.h
r333 r336 2 2 */ 3 3 4 #ifndef OPS_CRYPTO_H 5 #define OPS_CRYPTO_H 6 4 7 #include "util.h" 5 8 #include "packet.h" 6 7 #ifndef OPS_CRYPTO_H 8 #define OPS_CRYPTO_H 9 #include "packet-parse.h" 9 10 10 11 #define OPS_MAX_HASH 64 … … 23 24 ops_hash_add_t *add; 24 25 ops_hash_finish_t *finish; 26 void *data; 27 }; 28 29 typedef void ops_decrypt_init_t(ops_decrypt_t *decrypt); 30 typedef size_t ops_decrypt_decrypt_t(ops_decrypt_t *decrypt,void *out, 31 const void *in,int count); 32 typedef void ops_decrypt_finish_t(ops_decrypt_t *decrypt); 33 34 struct _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; 25 40 void *data; 26 41 }; … … 48 63 unsigned ops_block_size(ops_symmetric_algorithm_t alg); 49 64 65 int ops_decrypt_data(ops_region_t *region,ops_parse_info_t *parse_info); 66 67 void ops_decrypt_any(ops_decrypt_t *decrypt, 68 ops_symmetric_algorithm_t algorithm); 69 50 70 #endif openpgpsdk/trunk/include/openpgpsdk/errors.h
r332 r336 27 27 /* parser errors */ 28 28 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, 30 33 31 34 /* creator errors */ openpgpsdk/trunk/include/openpgpsdk/keyring.h
r241 r336 28 28 const ops_public_key_t * 29 29 ops_get_public_key_from_data(const ops_key_data_t *data); 30 ops_boolean_t ops_key_is_secret(const ops_key_data_t *data); 31 const ops_secret_key_t * 32 ops_get_secret_key_from_data(const ops_key_data_t *data); 33 ops_secret_key_t *ops_decrypt_secret_key_from_data(ops_key_data_t *key, 34 const char *pphrase); 35 36 void ops_keyring_read(ops_keyring_t *keyring,const char *file); 37 38 char *ops_get_passphrase(void); 30 39 31 40 #endif openpgpsdk/trunk/include/openpgpsdk/packet-parse.h
r335 r336 65 65 void ops_parse_info_delete(ops_parse_info_t *pinfo); 66 66 ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo); 67 ops_decrypt_t *ops_parse_get_decrypt(ops_parse_info_t *pinfo); 67 68 68 69 void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 69 70 void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 71 void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo); 70 72 void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 71 73 void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 74 void *ops_reader_get_arg_from_pinfo(ops_parse_info_t *pinfo); 72 75 73 76 void *ops_reader_get_arg(ops_reader_info_t *rinfo); 74 void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo);75 77 76 78 ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, openpgpsdk/trunk/include/openpgpsdk/packet.h
r335 r336 128 128 OPS_PTAG_CT_SECRET_SUBKEY = 7, /*!< Secret Subkey Packet */ 129 129 OPS_PTAG_CT_COMPRESSED = 8, /*!< Compressed Data Packet */ 130 OPS_PTAG_CT_S K_DATA = 9, /*!< Symmetrically Encrypted Data Packet */130 OPS_PTAG_CT_SE_DATA = 9, /*!< Symmetrically Encrypted Data Packet */ 131 131 OPS_PTAG_CT_MARKER =10, /*!< Marker Packet */ 132 132 OPS_PTAG_CT_LITERAL_DATA =11, /*!< Literal Data Packet */ … … 198 198 OPS_PTAG_CT_UNARMOURED_TEXT =0x300+9, 199 199 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, 200 202 201 203 /* commands to the callback */ 202 OPS_P TAG_CMD_GET_PASSPHRASE=0x400,204 OPS_PARSER_CMD_GET_PASSPHRASE =0x400, 203 205 204 206 … … 206 208 OPS_PARSER_ERROR =0x500, /*!< Internal Use: Parser Error */ 207 209 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,210 210 }; 211 211 … … 315 315 typedef enum 316 316 { 317 OPS_V2=2, /*<! Version 2 (essentially the same as v3) */ 317 318 OPS_V3=3, /*<! Version 3 */ 318 319 OPS_V4=4, /*<! Version 4 */ … … 394 395 } ops_symmetric_algorithm_t; 395 396 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 */ 404 typedef 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 396 416 // Maximum block size for symmetric crypto 397 417 #define OPS_MAX_BLOCK_SIZE 16 418 419 // Salt size for hashing 420 #define OPS_SALT_SIZE 8 398 421 399 422 /** ops_secret_key_t … … 405 428 ops_s2k_specifier_t s2k_specifier; 406 429 ops_symmetric_algorithm_t algorithm; 430 ops_hash_algorithm_t hash_algorithm; 431 unsigned char salt[OPS_SALT_SIZE]; 432 unsigned char iterations; 407 433 unsigned char iv[OPS_MAX_BLOCK_SIZE]; 408 434 unsigned checksum; … … 462 488 OPS_SIG_3RD_PARTY =0x50, /*<! Third-Party Confirmation signature */ 463 489 } 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.4471 */472 typedef enum473 {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;483 490 484 491 /** Struct to hold parameters of an RSA signature */ openpgpsdk/trunk/include/openpgpsdk/types.h
r307 r336 24 24 /** ops_content_tag_t */ 25 25 typedef enum ops_content_tag_t ops_content_tag_t; 26 27 typedef struct _ops_decrypt_t ops_decrypt_t; 26 28 27 29 /** ops_hash_t */ openpgpsdk/trunk/include/openpgpsdk/validate.h
r241 r336 1 1 void ops_validate_all_signatures(const ops_keyring_t *ring); 2 void ops_key_data_reader_set(ops_parse_info_t *pinfo, 3 const ops_key_data_t *key); openpgpsdk/trunk/src/accumulate.c
r335 r336 28 28 ops_keyring_t *keyring=arg->keyring; 29 29 ops_key_data_t *cur=&keyring->keys[keyring->nkeys]; 30 const ops_public_key_t *pkey; 30 31 31 32 switch(content_->tag) … … 38 39 EXPAND_ARRAY(keyring,keys); 39 40 41 if(content_->tag == OPS_PTAG_CT_PUBLIC_KEY) 42 pkey=&content->public_key; 43 else 44 pkey=&content->secret_key.public_key; 45 40 46 memset(&keyring->keys[keyring->nkeys],'\0', 41 47 sizeof keyring->keys[keyring->nkeys]); 42 48 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); 46 51 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; 48 58 return OPS_KEEP_MEMORY; 49 59 openpgpsdk/trunk/src/compress.c
r320 r336 119 119 memset(&arg,'\0',sizeof arg); 120 120 121 122 121 arg.region=region; 123 122 openpgpsdk/trunk/src/errors.c
r320 r336 11 11 12 12 #include "openpgpsdk/util.h" 13 14 #define ERR(code) { code, #code } 13 15 14 16 static ops_errcode_name_map_t errcode_name_map[] = … … 28 30 { OPS_E_P, "OPS_E_P" }, 29 31 { 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), 30 35 31 36 { OPS_E_C, "OPS_E_C" }, openpgpsdk/trunk/src/keyring.c
r250 r336 3 3 4 4 #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> 5 9 #include "keyring_local.h" 6 10 #include <stdlib.h> 7 11 #include <string.h> 12 #include <unistd.h> 13 #include <fcntl.h> 14 #include <assert.h> 8 15 9 16 ops_key_data_t * … … 34 41 key->packets=NULL; 35 42 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); 37 47 } 38 48 … … 55 65 const ops_public_key_t * 56 66 ops_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 73 ops_boolean_t ops_key_is_secret(const ops_key_data_t *data) 74 { return data->type != OPS_PTAG_CT_PUBLIC_KEY; } 75 76 const ops_secret_key_t * 77 ops_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 84 static ops_parse_cb_return_t 85 cb_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) */ 120 void 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 147 char *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 164 typedef struct 165 { 166 ops_key_data_t *key; 167 char *pphrase; 168 ops_secret_key_t *skey; 169 } decrypt_arg_t; 170 171 static 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 227 ops_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 9 9 } while(0) 10 10 11 typedef union 12 { 13 ops_public_key_t pkey; 14 ops_secret_key_t skey; 15 } ops_key_data_key_t; 16 17 11 18 // XXX: gonna have to expand this to hold onto subkeys, too... 12 19 struct ops_key_data … … 15 22 DECLARE_ARRAY(ops_packet_t,packets); 16 23 unsigned char keyid[8]; 17 ops_public_key_t pkey;18 24 ops_fingerprint_t fingerprint; 25 ops_content_tag_t type; 26 ops_key_data_key_t key; 19 27 }; openpgpsdk/trunk/src/packet-parse.c
r335 r336 113 113 /*! set error code in content and run CallBack to handle error */ 114 114 #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) 115 116 /*! set error text in content and run CallBack to handle error, then return */ 116 117 #define ERR(cbinfo,err) do { C.error.error=err; CB(cbinfo,OPS_PARSER_ERROR,&content); return ops_false; } while(0) … … 119 120 #define WARN(warn) do { C.error.error=warn; CB(OPS_PARSER_ERROR,&content);; } while(0) 120 121 #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)122 122 /*! \todo descr ERR1 macro */ 123 123 #define ERR1P(info,fmt,x) do { format_error(&content,(fmt),(x)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) … … 476 476 477 477 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 } 479 482 480 483 *pbn=BN_bin2bn(buf,length,NULL); … … 624 627 case OPS_PTAG_CT_ARMOUR_TRAILER: 625 628 case OPS_PTAG_CT_SIGNATURE_HEADER: 629 case OPS_PTAG_CT_SE_DATA: 626 630 break; 627 631 … … 732 736 case OPS_PARSER_ERROR: 733 737 case OPS_PARSER_ERRCODE: 734 case OPS_PARSER_ERROR_UNKNOWN_TAG:735 case OPS_PARSER_ERROR_PACKET_CONSUMED:736 738 break; 737 739 … … 745 747 break; 746 748 747 case OPS_P TAG_CMD_GET_PASSPHRASE:749 case OPS_PARSER_CMD_GET_PASSPHRASE: 748 750 ops_cmd_get_passphrase_free(c->content.passphrase); 749 751 break; … … 1773 1775 data_free(&remainder); 1774 1776 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); 1777 1778 } 1778 1779 else if(warn) … … 1806 1807 return 0; 1807 1808 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 } 1808 1828 } 1809 1829 else if(C.secret_key.s2k_usage != OPS_S2KU_NONE) 1810 1830 { 1831 // this is V3 style, looks just like a V4 simple hash 1811 1832 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) 1816 1839 { 1817 1840 int n; … … 1827 1850 passphrase=NULL; 1828 1851 pc.content.passphrase=&passphrase; 1829 CBP(parse_info,OPS_P TAG_CMD_GET_PASSPHRASE,&pc);1852 CBP(parse_info,OPS_PARSER_CMD_GET_PASSPHRASE,&pc); 1830 1853 if(!passphrase) 1831 1854 { … … 1911 1934 1912 1935 return 1; 1936 } 1937 1938 static 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); 1913 1948 } 1914 1949 … … 2034 2069 break; 2035 2070 2071 case OPS_PTAG_CT_SE_DATA: 2072 r=parse_se_data(®ion,parse_info); 2073 break; 2074 2036 2075 default: 2037 2076 format_error(&content,"Format error (unknown content tag %d)", 2038 2077 C.ptag.content_tag); 2039 CBP(parse_info,OPS_PARSER_ERROR_UNKNOWN_TAG,&content);2078 ERRCODEP(parse_info,OPS_E_P_UNKNOWN_TAG); 2040 2079 r=0; 2041 2080 } … … 2243 2282 ops_parse_cb_info_t *cbinfo) 2244 2283 { 2245 if (cbinfo->cb)2284 if(cbinfo->cb) 2246 2285 return cbinfo->cb(content,cbinfo); 2247 2286 else … … 2271 2310 { return rinfo->arg; } 2272 2311 2312 void *ops_reader_get_arg_from_pinfo(ops_parse_info_t *pinfo) 2313 { return pinfo->rinfo.arg; } 2314 2273 2315 ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo) 2274 2316 { return pinfo->errors; } 2275 2317 2318 ops_decrypt_t *ops_parse_get_decrypt(ops_parse_info_t *pinfo) 2319 { return pinfo->decrypt; } 2320 2276 2321 /* vim:set textwidth=120: */ 2277 2322 /* vim:set ts=8: */ openpgpsdk/trunk/src/packet-show.c
r333 r336 28 28 { OPS_PTAG_CT_SECRET_SUBKEY, "Secret Subkey" }, 29 29 { OPS_PTAG_CT_COMPRESSED, "Compressed Data" }, 30 { OPS_PTAG_CT_S K_DATA, "Symmetrically Encrypted Data" },30 { OPS_PTAG_CT_SE_DATA, "Symmetrically Encrypted Data" }, 31 31 { OPS_PTAG_CT_MARKER, "Marker" }, 32 32 { OPS_PTAG_CT_LITERAL_DATA, "Literal Data" }, openpgpsdk/trunk/src/parse_local.h
r334 r336 57 57 ops_parse_cb_info_t cbinfo; 58 58 ops_error_t *errors; 59 ops_decrypt_t *decrypt; 59 60 }; openpgpsdk/trunk/src/validate.c
r320 r336 4 4 #include <openpgpsdk/util.h> 5 5 #include <openpgpsdk/signature.h> 6 #include <openpgpsdk/validate.h> 6 7 #include <assert.h> 7 8 #include <string.h> … … 58 59 static ops_parse_cb_return_t 59 60 validate_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; 65 66 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; 72 73 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; 78 79 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; 85 86 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); 90 91 91 signer=ops_keyring_find_key_by_id(arg->keyring,92 signer=ops_keyring_find_key_by_id(arg->keyring, 92 93 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 } 98 99 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; 110 111 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; 117 119 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 else126 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; 128 130 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 139 void 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 } 136 151 137 152 static void validate_key_signatures(const ops_key_data_t *key, … … 140 155 ops_parse_info_t *pinfo; 141 156 validate_cb_arg_t carg; 142 validate_reader_arg_t rarg;143 157 144 memset(&rarg,'\0',sizeof rarg);145 158 memset(&carg,'\0',sizeof carg); 146 159 … … 148 161 // ops_parse_options(&opt,OPS_PTAG_CT_SIGNATURE,OPS_PARSE_PARSED); 149 162 150 rarg.key=key;151 rarg.packet=0;152 rarg.offset=0;153 154 163 carg.keyring=keyring; 155 carg.rarg=&rarg;156 164 157 165 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); 159 169 160 170 ops_parse(pinfo);
