[OpenPGP:SDK svn] r343 - in openpgpsdk/trunk: examples include/openpgpsdk src
Subversion
ben at algroup.co.uk
Mon Jan 30 16:10:44 GMT 2006
Author: ben
Date: 2006-01-30 16:10:43 +0000 (Mon, 30 Jan 2006)
New Revision: 343
Modified:
openpgpsdk/trunk/examples/packet-dump.c
openpgpsdk/trunk/include/openpgpsdk/crypto.h
openpgpsdk/trunk/include/openpgpsdk/packet.h
openpgpsdk/trunk/src/packet-parse.c
openpgpsdk/trunk/src/signature.c
openpgpsdk/trunk/src/symmetric.c
Log:
Working secret key decryption!
Modified: openpgpsdk/trunk/examples/packet-dump.c
===================================================================
--- openpgpsdk/trunk/examples/packet-dump.c 2006-01-30 13:36:42 UTC (rev 342)
+++ openpgpsdk/trunk/examples/packet-dump.c 2006-01-30 16:10:43 UTC (rev 343)
@@ -830,7 +830,7 @@
printf("Hash algorithm: %d\n",content->secret_key.hash_algorithm);
print_hexdump("Salt",content->secret_key.salt,
sizeof content->secret_key.salt);
- printf("Iterations: %d\n",content->secret_key.iterations);
+ printf("Octet count: %d\n",content->secret_key.octet_count);
print_hexdump("IV",content->secret_key.iv,
ops_block_size(content->secret_key.algorithm));
@@ -838,8 +838,6 @@
if(content_->tag == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY)
break;
- printf("Checksum: %04x\n",content->secret_key.checksum);
-
switch(content->secret_key.public_key.algorithm)
{
case OPS_PKA_RSA:
@@ -856,6 +854,13 @@
default:
assert(0);
}
+
+ if(content->secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED)
+ print_hexdump("Checkhash",content->secret_key.checkhash,
+ OPS_CHECKHASH_SIZE);
+ else
+ printf("Checksum: %04x\n",content->secret_key.checksum);
+
break;
case OPS_PTAG_CT_ARMOUR_HEADER:
Modified: openpgpsdk/trunk/include/openpgpsdk/crypto.h
===================================================================
--- openpgpsdk/trunk/include/openpgpsdk/crypto.h 2006-01-30 13:36:42 UTC (rev 342)
+++ openpgpsdk/trunk/include/openpgpsdk/crypto.h 2006-01-30 16:10:43 UTC (rev 343)
@@ -8,7 +8,8 @@
#include "packet.h"
#include "packet-parse.h"
-#define OPS_MAX_HASH 64
+#define OPS_MAX_HASH_SIZE 64
+#define OPS_MIN_HASH_SIZE 16
typedef void ops_hash_init_t(ops_hash_t *hash);
typedef void ops_hash_add_t(ops_hash_t *hash,const unsigned char *data,
@@ -75,6 +76,7 @@
const ops_rsa_public_key_t *rsa);
unsigned ops_block_size(ops_symmetric_algorithm_t alg);
+unsigned ops_key_size(ops_symmetric_algorithm_t alg);
int ops_decrypt_data(ops_region_t *region,ops_parse_info_t *parse_info);
Modified: openpgpsdk/trunk/include/openpgpsdk/packet.h
===================================================================
--- openpgpsdk/trunk/include/openpgpsdk/packet.h 2006-01-30 13:36:42 UTC (rev 342)
+++ openpgpsdk/trunk/include/openpgpsdk/packet.h 2006-01-30 16:10:43 UTC (rev 343)
@@ -421,6 +421,9 @@
// Salt size for hashing
#define OPS_SALT_SIZE 8
+// Hash size for secret key check
+#define OPS_CHECKHASH_SIZE 20
+
/** ops_secret_key_t
*/
typedef struct
@@ -431,10 +434,11 @@
ops_symmetric_algorithm_t algorithm;
ops_hash_algorithm_t hash_algorithm;
unsigned char salt[OPS_SALT_SIZE];
- unsigned iterations;
+ unsigned octet_count;
unsigned char iv[OPS_MAX_BLOCK_SIZE];
+ ops_secret_key_union_t key;
unsigned checksum;
- ops_secret_key_union_t key;
+ unsigned char checkhash[OPS_CHECKHASH_SIZE];
} ops_secret_key_t;
/** Structure to hold one trust packet's data */
Modified: openpgpsdk/trunk/src/packet-parse.c
===================================================================
--- openpgpsdk/trunk/src/packet-parse.c 2006-01-30 13:36:42 UTC (rev 342)
+++ openpgpsdk/trunk/src/packet-parse.c 2006-01-30 16:10:43 UTC (rev 343)
@@ -1792,6 +1792,7 @@
int ret=1;
ops_region_t encregion;
ops_region_t *saved_region=NULL;
+ size_t checksum_length=2;
memset(&content,'\0',sizeof content);
if(!parse_public_key_data(&C.secret_key.public_key,region,parse_info))
@@ -1800,6 +1801,9 @@
return 0;
C.secret_key.s2k_usage=c[0];
+ if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED)
+ checksum_length=20;
+
if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED
|| C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED)
{
@@ -1827,7 +1831,7 @@
{
if(!limited_read(c,1,region,parse_info))
return 0;
- C.secret_key.iterations=(16+(c[0]&15)) << ((c[0] >> 4)+6);
+ C.secret_key.octet_count=(16+(c[0]&15)) << ((c[0] >> 4)+6);
}
}
else if(C.secret_key.s2k_usage != OPS_S2KU_NONE)
@@ -1845,7 +1849,11 @@
int n;
ops_parser_content_t pc;
char *passphrase;
- unsigned char hash[OPS_MAX_HASH];
+ unsigned char key[OPS_MAX_KEY_SIZE+OPS_MAX_HASH_SIZE];
+ ops_hash_t hashes[(OPS_MAX_KEY_SIZE+OPS_MIN_HASH_SIZE-1)/OPS_MIN_HASH_SIZE];
+ int keysize;
+ int hashsize;
+ size_t l;
n=ops_block_size(C.secret_key.algorithm);
assert(n > 0 && n <= OPS_MAX_BLOCK_SIZE);
@@ -1866,17 +1874,75 @@
return 1;
}
- ops_hash(hash,C.secret_key.hash_algorithm,passphrase,
- strlen(passphrase));
+ keysize=ops_key_size(C.secret_key.algorithm);
+ assert(keysize > 0 && keysize <= OPS_MAX_KEY_SIZE);
+ hashsize=ops_hash_size(C.secret_key.hash_algorithm);
+ assert(hashsize > 0 && hashsize <= OPS_MAX_HASH_SIZE);
+
+ for(n=0 ; n*hashsize < keysize ; ++n)
+ {
+ int i;
+
+ ops_hash_any(&hashes[n],C.secret_key.hash_algorithm);
+ hashes[n].init(&hashes[n]);
+ // preload hashes with zeroes...
+ for(i=0 ; i < n ; ++i)
+ hashes[n].add(&hashes[n],"",1);
+ }
+
+ l=strlen(passphrase);
+
+ for(n=0 ; n*hashsize < keysize ; ++n)
+ {
+ unsigned i;
+
+ switch(C.secret_key.s2k_specifier)
+ {
+ case OPS_S2KS_SALTED:
+ hashes[n].add(&hashes[n],C.secret_key.salt,OPS_SALT_SIZE);
+ // flow through...
+ case OPS_S2KS_SIMPLE:
+ hashes[n].add(&hashes[n],passphrase,l);
+ break;
+
+ case OPS_S2KS_ITERATED_AND_SALTED:
+ for(i=0 ; i < C.secret_key.octet_count ; i+=l+OPS_SALT_SIZE)
+ {
+ int j=l+OPS_SALT_SIZE;
+
+ if(i+j > C.secret_key.octet_count && i != 0)
+ j=C.secret_key.octet_count-i;
+
+ hashes[n].add(&hashes[n],C.secret_key.salt,
+ j > OPS_SALT_SIZE ? OPS_SALT_SIZE : j);
+ if(j > OPS_SALT_SIZE)
+ hashes[n].add(&hashes[n],passphrase,j-OPS_SALT_SIZE);
+ }
+
+ }
+ }
+
+ for(n=0 ; n*hashsize < keysize ; ++n)
+ {
+ int r=hashes[n].finish(&hashes[n],key+n*hashsize);
+ assert(r == hashsize);
+ }
+
ops_decrypt_any(&decrypt,C.secret_key.algorithm);
decrypt.set_iv(&decrypt,C.secret_key.iv);
- decrypt.set_key(&decrypt,hash);
+ decrypt.set_key(&decrypt,key);
+ /* We need to prevent the decrypter from reading the trailing
+ checksum */
+ region->length-=checksum_length;
ops_reader_push_decrypt(parse_info,&decrypt,region);
- /* Since all known encryption for PGP doesn't compress, we can limit
- to the same length as the current region (for now) */
+ /* Since all known encryption for PGP doesn't compress, we can
+ limit to the same length as the current region (for now),
+ allowing for the trailing checksum.
+ */
+
ops_init_subregion(&encregion,NULL);
encregion.length=region->length-region->length_read;
saved_region=region;
@@ -1911,16 +1977,28 @@
if(saved_region)
{
ops_reader_pop_decrypt(parse_info);
+ assert(region->length_read == region->length);
region=saved_region;
+ /* put back checksum data */
+ region->length+=checksum_length;
}
if(!ret)
return 0;
- if(!limited_read_scalar(&C.secret_key.checksum,2,region,parse_info))
- return 0;
// XXX: check the checksum
+ if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED)
+ {
+ if(!limited_read(C.secret_key.checkhash,20,region,parse_info))
+ return 0;
+ }
+ else
+ {
+ if(!limited_read_scalar(&C.secret_key.checksum,2,region,parse_info))
+ return 0;
+ }
+
CBP(parse_info,OPS_PTAG_CT_SECRET_KEY,&content);
return 1;
Modified: openpgpsdk/trunk/src/signature.c
===================================================================
--- openpgpsdk/trunk/src/signature.c 2006-01-30 13:36:42 UTC (rev 342)
+++ openpgpsdk/trunk/src/signature.c 2006-01-30 16:10:43 UTC (rev 343)
@@ -217,7 +217,7 @@
const ops_public_key_t *signer)
{
int n;
- unsigned char hashout[OPS_MAX_HASH];
+ unsigned char hashout[OPS_MAX_HASH_SIZE];
n=hash->finish(hash,hashout);
Modified: openpgpsdk/trunk/src/symmetric.c
===================================================================
--- openpgpsdk/trunk/src/symmetric.c 2006-01-30 13:36:42 UTC (rev 342)
+++ openpgpsdk/trunk/src/symmetric.c 2006-01-30 16:10:43 UTC (rev 343)
@@ -3,34 +3,11 @@
#include <assert.h>
#include <openssl/cast.h>
-unsigned ops_block_size(ops_symmetric_algorithm_t alg)
- {
- // perhaps do this via the underlying algorithm later
- switch(alg)
- {
- case OPS_SA_PLAINTEXT:
- return 1;
-
- case OPS_SA_IDEA:
- case OPS_SA_TRIPLEDES:
- case OPS_SA_CAST5:
- case OPS_SA_BLOWFISH:
- case OPS_SA_TWOFISH:
- return 8;
-
- case OPS_SA_AES_128:
- case OPS_SA_AES_192:
- case OPS_SA_AES_256:
- return 16;
- }
-
- return 0;
- }
-
typedef struct
{
unsigned char decrypted[1024];
size_t decrypted_count;
+ size_t decrypted_offset;
ops_decrypt_t *decrypt;
ops_region_t *region;
} encrypted_arg_t;
@@ -58,8 +35,9 @@
else
n=length;
- memcpy(dest,arg->decrypted,n);
+ memcpy(dest,arg->decrypted+arg->decrypted_offset,n);
arg->decrypted_count-=n;
+ arg->decrypted_offset+=n;
length-=n;
dest+=n;
}
@@ -88,6 +66,8 @@
arg->decrypted,
buffer,n);
assert(arg->decrypted_count > 0);
+
+ arg->decrypted_offset=0;
}
}
@@ -173,16 +153,39 @@
TRAILER
};
-void ops_decrypt_any(ops_decrypt_t *decrypt,ops_symmetric_algorithm_t alg)
+static ops_decrypt_t *get_proto(ops_symmetric_algorithm_t alg)
{
switch(alg)
{
case OPS_SA_CAST5:
- *decrypt=cast5;
- break;
+ return &cast5;
default:
assert(0);
}
+
+ return NULL;
}
+void ops_decrypt_any(ops_decrypt_t *decrypt,ops_symmetric_algorithm_t alg)
+ { *decrypt=*get_proto(alg); }
+
+unsigned ops_block_size(ops_symmetric_algorithm_t alg)
+ {
+ ops_decrypt_t *p=get_proto(alg);
+
+ if(!p)
+ return 0;
+
+ return p->blocksize;
+ }
+
+unsigned ops_key_size(ops_symmetric_algorithm_t alg)
+ {
+ ops_decrypt_t *p=get_proto(alg);
+
+ if(!p)
+ return 0;
+
+ return p->keysize;
+ }
More information about the OpenPGPsdk-svn
mailing list