Changeset 383
- Timestamp:
- 02/22/06 11:35:13
- Files:
-
- openpgpsdk/trunk/examples/packet-dump.c (modified) (3 diffs)
- openpgpsdk/trunk/include/openpgpsdk/crypto.h (modified) (6 diffs)
- openpgpsdk/trunk/include/openpgpsdk/packet.h (modified) (5 diffs)
- openpgpsdk/trunk/src/Makefile.template (modified) (1 diff)
- openpgpsdk/trunk/src/crypto.c (added)
- openpgpsdk/trunk/src/keyring.c (modified) (1 diff)
- openpgpsdk/trunk/src/openssl_crypto.c (modified) (1 diff)
- openpgpsdk/trunk/src/packet-parse.c (modified) (6 diffs)
- openpgpsdk/trunk/src/symmetric.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
openpgpsdk/trunk/examples/packet-dump.c
r373 r383 377 377 else 378 378 printf("Checksum: %04x\n",sk->checksum); 379 } 380 381 static void print_pk_session_key(ops_content_tag_t tag, 382 const ops_pk_session_key_t *key) 383 { 384 if(tag == OPS_PTAG_CT_PK_SESSION_KEY) 385 print_tagname("PUBLIC KEY SESSION KEY"); 386 else 387 print_tagname("ENCRYPTED PUBLIC KEY SESSION KEY"); 388 389 printf("Version: %d\n",key->version); 390 print_hexdump("key ID",key->key_id,sizeof key->key_id); 391 printf("Algorithm: %d (%s)\n",key->algorithm, 392 ops_show_pka(key->algorithm)); 393 switch(key->algorithm) 394 { 395 case OPS_PKA_RSA: 396 print_bn("encrypted_m",key->parameters.rsa.encrypted_m); 397 break; 398 399 case OPS_PKA_ELGAMAL: 400 print_bn("g_to_k",key->parameters.elgamal.g_to_k); 401 print_bn("encrypted_m",key->parameters.elgamal.encrypted_m); 402 break; 403 404 default: 405 assert(0); 406 } 379 407 } 380 408 … … 932 960 933 961 case OPS_PTAG_CT_PK_SESSION_KEY: 934 print_tagname("PUBLIC KEY SESSION KEY"); 935 printf("Version: %d\n",content->pk_session_key.version); 936 print_hexdump("key ID",content->pk_session_key.key_id, 937 sizeof content->pk_session_key.key_id); 938 printf("Algorithm: %d (%s)\n",content->pk_session_key.algorithm, 939 ops_show_symmetric_algorithm(content->pk_session_key.algorithm)); 940 switch(content->pk_session_key.algorithm) 941 { 942 case OPS_PKA_RSA: 943 print_bn("encrypted_m", 944 content->pk_session_key.parameters.rsa.encrypted_m); 945 break; 946 947 case OPS_PKA_ELGAMAL: 948 print_bn("g_to_k", 949 content->pk_session_key.parameters.elgamal.g_to_k); 950 print_bn("encrypted_m", 951 content->pk_session_key.parameters.elgamal.encrypted_m); 952 break; 953 954 default: 955 assert(0); 956 } 957 958 /* Now get hold of session key for later on */ 962 print_pk_session_key(content_->tag,&content->pk_session_key); 963 break; 964 965 case OPS_PARSER_CMD_GET_SECRET_KEY: 966 print_pk_session_key(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, 967 content->get_secret_key.pk_session_key); 959 968 960 969 decrypter=ops_keyring_find_key_by_id(&keyring, 961 content-> pk_session_key.key_id);970 content->get_secret_key.pk_session_key->key_id); 962 971 if(!decrypter || !ops_key_is_secret(decrypter)) 963 972 break; … … 973 982 free(phrase); 974 983 } 984 985 *content->get_secret_key.secret_key=secret; 975 986 976 987 break; openpgpsdk/trunk/include/openpgpsdk/crypto.h
r373 r383 34 34 typedef void ops_decrypt_init_t(ops_decrypt_t *decrypt); 35 35 typedef void ops_decrypt_resync_t(ops_decrypt_t *decrypt); 36 typedef size_t ops_decrypt_decrypt_t(ops_decrypt_t *decrypt,void *out, 37 const void *in,int count); 36 //typedef size_t ops_decrypt_decrypt_t(ops_decrypt_t *decrypt,void *out, 37 // const void *in,int count); 38 typedef void ops_decrypt_block_encrypt_t(ops_decrypt_t *decrypt,void *out, 39 const void *in); 38 40 typedef void ops_decrypt_finish_t(ops_decrypt_t *decrypt); 39 41 … … 45 47 ops_decrypt_set_iv_t *set_iv; /* Call this before init! */ 46 48 ops_decrypt_set_iv_t *set_key; /* Call this before init! */ 47 ops_decrypt_init_t * init;49 ops_decrypt_init_t *base_init; 48 50 ops_decrypt_resync_t *resync; 49 ops_decrypt_decrypt_t *decrypt; 51 // ops_decrypt_decrypt_t *decrypt; 52 ops_decrypt_block_encrypt_t *block_encrypt; 50 53 ops_decrypt_finish_t *finish; 51 54 unsigned char iv[OPS_MAX_BLOCK_SIZE]; … … 53 56 unsigned char siv[OPS_MAX_BLOCK_SIZE]; /* Needed for weird v3 resync */ 54 57 unsigned char key[OPS_MAX_KEY_SIZE]; 55 int num;58 size_t num; 56 59 void *data; 57 60 }; … … 78 81 size_t length,const ops_rsa_secret_key_t *srsa, 79 82 const ops_rsa_public_key_t *rsa); 83 int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in, 84 size_t length,const ops_rsa_secret_key_t *srsa, 85 const ops_rsa_public_key_t *rsa); 80 86 81 87 unsigned ops_block_size(ops_symmetric_algorithm_t alg); … … 86 92 87 93 void ops_decrypt_any(ops_decrypt_t *decrypt,ops_symmetric_algorithm_t alg); 94 void ops_decrypt_init(ops_decrypt_t *decrypt); 95 size_t ops_decrypt_decrypt(ops_decrypt_t *decrypt,void *out,const void *in, 96 size_t count); 88 97 89 98 void ops_reader_push_decrypt(ops_parse_info_t *pinfo,ops_decrypt_t *decrypt, … … 95 104 void ops_reader_pop_hash(ops_parse_info_t *pinfo); 96 105 106 int ops_decrypt_mpi(unsigned char *buf,unsigned buflen,const BIGNUM *encmpi, 107 const ops_secret_key_t *skey); 108 97 109 #endif openpgpsdk/trunk/include/openpgpsdk/packet.h
r373 r383 202 202 OPS_PTAG_CT_SE_IP_DATA_HEADER =0x300+13, 203 203 OPS_PTAG_CT_SE_IP_DATA_BODY =0x300+14, 204 OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY=0x300+15, 204 205 205 206 /* commands to the callback */ 206 207 OPS_PARSER_CMD_GET_SK_PASSPHRASE =0x400, 208 OPS_PARSER_CMD_GET_SECRET_KEY =0x400+1, 207 209 208 210 … … 809 811 { 810 812 BIGNUM *encrypted_m; 813 BIGNUM *m; 811 814 } ops_pk_session_key_parameters_rsa_t; 812 815 … … 829 832 ops_public_key_algorithm_t algorithm; 830 833 ops_pk_session_key_parameters_t parameters; 834 ops_symmetric_algorithm_t symmetric_algorithm; 835 unsigned char key[OPS_MAX_KEY_SIZE]; 836 unsigned short checksum; 831 837 } ops_pk_session_key_t; 832 838 … … 852 858 unsigned char data[8192]; 853 859 } ops_se_data_body_t; 860 861 typedef struct 862 { 863 const ops_secret_key_t **secret_key; 864 const ops_pk_session_key_t *pk_session_key; 865 } ops_get_secret_key_t; 854 866 855 867 /** ops_parser_union_content_t */ … … 901 913 ops_se_ip_data_header_t se_ip_data_header; 902 914 ops_se_data_body_t se_data_body; 915 ops_get_secret_key_t get_secret_key; 903 916 } ops_parser_content_union_t; 904 917 openpgpsdk/trunk/src/Makefile.template
r333 r383 12 12 memory.o fingerprint.o hash.o keyring.o signature.o compress.o \ 13 13 packet-show.o create.o validate.o lists.o armour.o errors.o \ 14 symmetric.o 14 symmetric.o crypto.o 15 15 16 16 headers: openpgpsdk/trunk/src/keyring.c
r371 r383 285 285 return arg.skey; 286 286 } 287 openpgpsdk/trunk/src/openssl_crypto.c
r371 r383 145 145 } 146 146 147 int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in, 148 size_t length,const ops_rsa_secret_key_t *srsa, 149 const ops_rsa_public_key_t *rsa) 150 { 151 RSA *orsa; 152 int n; 153 154 orsa=RSA_new(); 155 orsa->n=rsa->n; // XXX: do we need n? 156 orsa->d=srsa->d; 157 orsa->p=srsa->q; 158 orsa->q=srsa->p; 159 160 /* debug */ 161 orsa->e=rsa->e; 162 assert(RSA_check_key(orsa) == 1); 163 orsa->e=NULL; 164 /* end debug */ 165 166 n=RSA_private_decrypt(length,in,out,orsa,RSA_NO_PADDING); 167 168 orsa->n=orsa->d=orsa->p=orsa->q=NULL; 169 RSA_free(orsa); 170 171 return n; 172 } 173 147 174 void ops_crypto_init() 148 175 { openpgpsdk/trunk/src/packet-parse.c
r373 r383 124 124 /*! \todo descr ERR1 macro */ 125 125 #define ERR1P(info,fmt,x) do { format_error(&content,(fmt),(x)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 126 #define ERR2P(info,fmt,x,y) do { format_error(&content,(fmt),(x),(y)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 126 127 127 128 /* XXX: replace ops_ptag_t with something more appropriate for limiting … … 636 637 case OPS_PTAG_CT_SE_IP_DATA_HEADER: 637 638 case OPS_PTAG_CT_SE_IP_DATA_BODY: 639 case OPS_PARSER_CMD_GET_SECRET_KEY: 638 640 break; 639 641 … … 2064 2066 unsigned char c[1]; 2065 2067 ops_parser_content_t content; 2068 ops_parser_content_t pc; 2069 unsigned char buf[8192]; 2070 int n; 2071 BIGNUM *enc_m; 2072 unsigned k; 2073 const ops_secret_key_t *secret; 2066 2074 2067 2075 if(!limited_read(c,1,region,parse_info)) … … 2086 2094 region,parse_info)) 2087 2095 return 0; 2096 enc_m=C.pk_session_key.parameters.rsa.encrypted_m; 2088 2097 break; 2089 2098 … … 2094 2103 region,parse_info)) 2095 2104 return 0; 2105 enc_m=C.pk_session_key.parameters.elgamal.encrypted_m; 2096 2106 break; 2097 2107 … … 2102 2112 return 0; 2103 2113 } 2114 2115 memset(&pc,'\0',sizeof pc); 2116 secret=NULL; 2117 pc.content.get_secret_key.secret_key=&secret; 2118 pc.content.get_secret_key.pk_session_key=&C.pk_session_key; 2119 2120 CBP(parse_info,OPS_PARSER_CMD_GET_SECRET_KEY,&pc); 2121 2122 if(!secret) 2123 { 2124 CBP(parse_info,OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY,&content); 2125 2126 return 1; 2127 } 2128 2129 n=ops_decrypt_mpi(buf,sizeof buf,enc_m,secret); 2130 2131 if(n < 1) 2132 ERRP(parse_info,"decrypted message too short"); 2133 2134 C.pk_session_key.symmetric_algorithm=buf[0]; 2135 k=ops_key_size(C.pk_session_key.symmetric_algorithm); 2136 2137 if((unsigned)n != k+3) 2138 ERR2P(parse_info,"decrypted message wrong length (got %d expected %d)", 2139 n,k+3); 2140 2141 assert(k <= sizeof C.pk_session_key.key); 2142 2143 memcpy(C.pk_session_key.key,buf+1,k); 2144 2145 C.pk_session_key.checksum=buf[k+1]+(buf[k+2] << 8); 2146 2147 // XXX: Check checksum! 2104 2148 2105 2149 CBP(parse_info,OPS_PTAG_CT_PK_SESSION_KEY,&content); openpgpsdk/trunk/src/symmetric.c
r373 r383 4 4 #include <openssl/cast.h> 5 5 #include <openssl/idea.h> 6 #include <openssl/aes.h> 6 7 #include "parse_local.h" 7 8 … … 91 92 if(!rinfo->pinfo->reading_v3_secret 92 93 || !rinfo->pinfo->reading_mpi_length) 93 arg->decrypted_count= arg->decrypt->decrypt(arg->decrypt,94 arg->decrypted,95 buffer,n);94 arg->decrypted_count=ops_decrypt_decrypt(arg->decrypt, 95 arg->decrypted, 96 buffer,n); 96 97 else 97 98 { … … 117 118 arg->region=region; 118 119 119 arg->decrypt->init(arg->decrypt);120 ops_decrypt_init(arg->decrypt); 120 121 121 122 ops_reader_push(pinfo,encrypted_data_reader,arg); … … 138 139 { memcpy(decrypt->key,key,decrypt->keysize); } 139 140 140 /* Only IDEA has a resync operation */141 141 static void std_resync(ops_decrypt_t *decrypt) 142 142 { 143 OPS_USED(decrypt); 144 145 assert(0); 143 if(decrypt->num == decrypt->blocksize) 144 return; 145 146 memmove(decrypt->civ+decrypt->blocksize-decrypt->num,decrypt->civ, 147 decrypt->num); 148 memcpy(decrypt->civ,decrypt->siv+decrypt->num, 149 decrypt->blocksize-decrypt->num); 150 decrypt->num=0; 146 151 } 147 152 … … 157 162 decrypt->data=malloc(sizeof(CAST_KEY)); 158 163 CAST_set_key(decrypt->data,decrypt->keysize,decrypt->key); 159 memcpy(decrypt->civ,decrypt->iv,decrypt->blocksize); 160 decrypt->num=0; 161 } 162 163 static size_t cast5_decrypt(ops_decrypt_t *decrypt,void *out,const void *in, 164 int count) 165 { 166 CAST_cfb64_encrypt(in,out,count,decrypt->data,decrypt->civ,&decrypt->num, 167 0); 168 169 return count; 170 } 164 } 165 166 static void cast5_encrypt(ops_decrypt_t *decrypt,void *out,const void *in) 167 { CAST_ecb_encrypt(in,out,decrypt->data,1); } 171 168 172 169 #define TRAILER "","","","",0,NULL … … 181 178 cast5_init, 182 179 std_resync, 183 cast5_ decrypt,180 cast5_encrypt, 184 181 std_finish, 185 182 TRAILER … … 195 192 // note that we don't invert the key for CFB mode 196 193 idea_set_encrypt_key(decrypt->key,decrypt->data); 197 198 memcpy(decrypt->civ,decrypt->iv,decrypt->blocksize); 199 idea_ecb_encrypt(decrypt->civ,decrypt->siv,decrypt->data); 200 201 decrypt->num=0; 202 } 203 204 static void idea_resync(ops_decrypt_t *decrypt) 205 { 206 if(decrypt->num == 8) 207 return; 208 209 memmove(decrypt->civ+8-decrypt->num,decrypt->civ,decrypt->num); 210 memcpy(decrypt->civ,decrypt->siv+decrypt->num,8-decrypt->num); 211 decrypt->num=0; 212 } 213 214 static size_t idea_decrypt(ops_decrypt_t *decrypt,void *out_,const void *in_, 215 int count) 216 { 217 unsigned char *out=out_; 218 const unsigned char *in=in_; 219 int saved=count; 220 221 /* in order to support v3's weird resyncing we have to implement CFB mode 222 ourselves */ 223 while(count-- > 0) 224 { 225 unsigned char t; 226 227 if(decrypt->num == 8) 228 { 229 memcpy(decrypt->siv,decrypt->civ,sizeof decrypt->siv); 230 idea_ecb_encrypt(decrypt->civ,decrypt->civ,decrypt->data); 231 decrypt->num=0; 232 } 233 t=decrypt->civ[decrypt->num]; 234 *out++=t^(decrypt->civ[decrypt->num++]=*in++); 235 } 236 237 return saved; 238 } 239 240 static ops_decrypt_t idea= 194 } 195 196 static void idea_block_encrypt(ops_decrypt_t *decrypt,void *out,const void *in) 197 { idea_ecb_encrypt(in,out,decrypt->data); } 198 199 static const ops_decrypt_t idea= 241 200 { 242 201 OPS_SA_IDEA, … … 246 205 std_set_key, 247 206 idea_init, 248 idea_resync,249 idea_ decrypt,207 std_resync, 208 idea_block_encrypt, 250 209 std_finish, 251 210 TRAILER 252 211 }; 253 212 254 static ops_decrypt_t *get_proto(ops_symmetric_algorithm_t alg) 213 static void aes256_init(ops_decrypt_t *decrypt) 214 { 215 free(decrypt->data); 216 decrypt->data=malloc(sizeof(AES_KEY)); 217 AES_set_encrypt_key(decrypt->key,256,decrypt->data); 218 } 219 220 static void aes_block_encrypt(ops_decrypt_t *decrypt,void *out,const void *in) 221 { AES_encrypt(in,out,decrypt->data); } 222 223 static const ops_decrypt_t aes256= 224 { 225 OPS_SA_AES_256, 226 AES_BLOCK_SIZE, 227 256/8, 228 std_set_iv, 229 std_set_key, 230 aes256_init, 231 std_resync, 232 aes_block_encrypt, 233 std_finish, 234 TRAILER 235 }; 236 237 static const ops_decrypt_t *get_proto(ops_symmetric_algorithm_t alg) 255 238 { 256 239 switch(alg) … … 262 245 return &idea; 263 246 247 case OPS_SA_AES_256: 248 return &aes256; 249 264 250 default: 251 // XXX: remove these 252 fprintf(stderr,"Unknown algorithm: %d\n",alg); 265 253 assert(0); 266 254 } … … 274 262 unsigned ops_block_size(ops_symmetric_algorithm_t alg) 275 263 { 276 ops_decrypt_t *p=get_proto(alg);264 const ops_decrypt_t *p=get_proto(alg); 277 265 278 266 if(!p) … … 284 272 unsigned ops_key_size(ops_symmetric_algorithm_t alg) 285 273 { 286 ops_decrypt_t *p=get_proto(alg);274 const ops_decrypt_t *p=get_proto(alg); 287 275 288 276 if(!p) … … 291 279 return p->keysize; 292 280 } 281 282 void ops_decrypt_init(ops_decrypt_t *decrypt) 283 { 284 decrypt->base_init(decrypt); 285 memcpy(decrypt->civ,decrypt->iv,decrypt->blocksize); 286 decrypt->block_encrypt(decrypt,decrypt->siv,decrypt->civ); 287 decrypt->num=0; 288 } 289 290 size_t ops_decrypt_decrypt(ops_decrypt_t *decrypt,void *out_,const void *in_, 291 size_t count) 292 { 293 unsigned char *out=out_; 294 const unsigned char *in=in_; 295 int saved=count; 296 297 /* in order to support v3's weird resyncing we have to implement CFB mode 298 ourselves */ 299 while(count-- > 0) 300 { 301 unsigned char t; 302 303 if(decrypt->num == decrypt->blocksize) 304 { 305 memcpy(decrypt->siv,decrypt->civ,decrypt->blocksize); 306 decrypt->block_encrypt(decrypt,decrypt->civ,decrypt->civ); 307 decrypt->num=0; 308 } 309 t=decrypt->civ[decrypt->num]; 310 *out++=t^(decrypt->civ[decrypt->num++]=*in++); 311 } 312 313 return saved; 314 } 315
