Changeset 304
- Timestamp:
- 11/24/05 09:53:05
- Files:
-
- openpgpsdk/trunk/configure (modified) (1 diff)
- openpgpsdk/trunk/examples/Makefile.template (modified) (4 diffs)
- openpgpsdk/trunk/examples/common.c (modified) (1 diff)
- openpgpsdk/trunk/examples/common.h (modified) (1 diff)
- openpgpsdk/trunk/examples/create-signed-key.c (modified) (3 diffs)
- openpgpsdk/trunk/include/openpgpsdk/create.h (modified) (2 diffs)
- openpgpsdk/trunk/include/openpgpsdk/crypto.h (modified) (1 diff)
- openpgpsdk/trunk/include/openpgpsdk/signature.h (modified) (3 diffs)
- openpgpsdk/trunk/include/openpgpsdk/types.h (modified) (1 diff)
- openpgpsdk/trunk/src/create.c (modified) (5 diffs)
- openpgpsdk/trunk/src/packet-parse.c (modified) (1 diff)
- openpgpsdk/trunk/src/signature.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
openpgpsdk/trunk/configure
r303 r304 38 38 $Subst{INCLUDES}.=" -I $loc/include"; 39 39 $Subst{CRYPTO_LIBS}="$loc/lib/libcrypto.a"; 40 # assume developer version if library isn't in .../lib 40 41 $Subst{CRYPTO_LIBS}="$loc/libcrypto.a" 41 42 if !-f $Subst{CRYPTO_LIBS}; openpgpsdk/trunk/examples/Makefile.template
r297 r304 9 9 10 10 all: Makefile lib .depend packet-dump verify create-key create-signed-key \ 11 verify2 11 verify2 sign-detached 12 12 13 test: test-dump test-verify 13 test: test-dump test-verify test-verify-armoured test-create-key 14 14 15 15 lib: … … 30 30 create-signed-key: create-signed-key.o $(LIBDEPS) 31 31 $(CC) $(LDFLAGS) -o create-signed-key create-signed-key.o $(LIBS) 32 33 sign-detached: sign-detached.o $(LIBDEPS) 34 $(CC) $(LDFLAGS) -o sign-detached sign-detached.o $(LIBS) 32 35 33 36 tags: … … 51 54 # tests 52 55 56 SCRATCH=../scratch 57 58 $(SCRATCH): 59 mkdir $(SCRATCH) 60 53 61 test-dump: packet-dump 54 62 ./packet-dump < ../test/dsa-public-key-2118CF83.raw … … 65 73 ./verify2 -a ../test/rsa-public-key-2719AF35.raw ../test/clearsign.txt 66 74 75 test-create-key: $(SCRATCH) 76 ./create-signed-key "A Test Key" $(SCRATCH)/key.sec $(SCRATCH)/key.pub 77 67 78 include .depend openpgpsdk/trunk/examples/common.c
r297 r304 19 19 } 20 20 21 ops_secret_key_t *get_ key(const char *keyfile)21 ops_secret_key_t *get_secret_key(const char *keyfile) 22 22 { 23 23 ops_reader_fd_arg_t arg; openpgpsdk/trunk/examples/common.h
r297 r304 1 1 #include <openpgpsdk/packet-parse.h> 2 2 3 ops_secret_key_t *get_ key(const char *keyfile);3 ops_secret_key_t *get_secret_key(const char *keyfile); openpgpsdk/trunk/examples/create-signed-key.c
r301 r304 4 4 #include <openpgpsdk/signature.h> 5 5 #include <openpgpsdk/packet-parse.h> 6 #include <openssl/rsa.h> 6 7 #include <stdio.h> 7 8 #include <fcntl.h> 8 9 #include <string.h> 9 #include <assert.h> 10 #include <unistd.h> 11 12 // XXX: rename to create-self-signed-key 10 13 11 14 /* … … 23 26 unsigned char keyid[OPS_KEY_ID_SIZE]; 24 27 unsigned char *user_id; /* not const coz we use _fast_ */ 25 const char *keyfile; 26 ops_secret_key_t *skey; 28 ops_secret_key_t skey; 29 RSA *rsa; 30 const char *secfile; 31 const char *pubfile; 32 BIGNUM *f4; 27 33 28 29 if(argc != 3) 34 if(argc != 4) 30 35 { 31 fprintf(stderr,"%s <secret key file> <user_id>\n",argv[0]); 36 fprintf(stderr,"%s <user_id> <secret key file> <public key file>\n", 37 argv[0]); 32 38 exit(1); 33 39 } 34 40 35 keyfile=argv[1]; 36 user_id=(unsigned char *)argv[2]; 41 user_id=argv[1]; 42 secfile=argv[2]; 43 pubfile=argv[3]; 44 45 f4=BN_new(); 46 BN_set_word(f4,RSA_F4); 47 48 rsa=RSA_new(); 49 RSA_generate_key_ex(rsa,1024,f4,NULL); 37 50 38 51 ops_init(); 39 52 40 skey=get_key(keyfile); 41 assert(skey); 53 // OpenSSL has p and q reversed relative to OpenPGP 54 ops_fast_create_rsa_secret_key(&skey,time(NULL),rsa->q,rsa->p,rsa->d, 55 rsa->iqmp,rsa->n,rsa->e); 42 56 43 arg.fd=1; 57 skey.key.rsa.p=rsa->q; 58 skey.key.rsa.q=rsa->p; 59 skey.key.rsa.d=rsa->d; 60 skey.key.rsa.u=rsa->iqmp; 61 62 arg.fd=open(secfile,O_CREAT|O_TRUNC|O_WRONLY,0666); 63 if(arg.fd < 0) 64 { 65 perror(secfile); 66 exit(2); 67 } 68 44 69 info.writer=ops_writer_fd; 45 70 info.arg=&arg; 46 71 47 ops_write_struct_public_key(&skey->public_key,&info); 72 ops_write_struct_secret_key(&skey,&info); 73 74 close(arg.fd); 75 76 arg.fd=open(pubfile,O_CREAT|O_TRUNC|O_WRONLY,0666); 77 if(arg.fd < 0) 78 { 79 perror(pubfile); 80 exit(2); 81 } 82 83 ops_write_struct_public_key(&skey.public_key,&info); 48 84 49 85 ops_fast_create_user_id(&id,user_id); 50 86 ops_write_struct_user_id(&id,&info); 51 87 52 ops_signature_start(&sig,&skey->public_key,&id,OPS_CERT_POSITIVE); 88 ops_signature_start_key_signature(&sig,&skey.public_key,&id, 89 OPS_CERT_POSITIVE); 53 90 ops_signature_add_creation_time(&sig,time(NULL)); 54 91 55 ops_keyid(keyid,&skey ->public_key);92 ops_keyid(keyid,&skey.public_key); 56 93 ops_signature_add_issuer_key_id(&sig,keyid); 57 94 … … 60 97 ops_signature_hashed_subpackets_end(&sig); 61 98 62 ops_write_signature(&sig,&skey->public_key,skey,&info); 63 64 ops_secret_key_free(skey); 99 ops_write_signature(&sig,&skey.public_key,&skey,&info); 65 100 66 101 ops_finish(); 67 102 103 close(arg.fd); 104 68 105 return 0; 69 106 } openpgpsdk/trunk/include/openpgpsdk/create.h
r302 r304 46 46 typedef struct ops_create_info ops_create_info_t; 47 47 48 49 /** \ingroup Create50 * needed for signature creation51 */52 typedef struct53 {54 ops_packet_writer_t *writer; /*!< The writer function */55 void *arg; /*!< Arguments for the writer function */56 ops_hash_t hash;57 ops_signature_t sig;58 ops_memory_t mem;59 ops_create_info_t info; /*!< how to do the writing */60 unsigned hashed_count_offset;61 unsigned hashed_data_length;62 unsigned unhashed_count_offset;63 } ops_create_signature_t;64 65 48 ops_boolean_t ops_write(const void *src,unsigned length, 66 49 ops_create_info_t *opt); … … 90 73 ops_boolean_t ops_write_user_id(const unsigned char *user_id,ops_create_info_t *opt); 91 74 75 void ops_create_rsa_secret_key(ops_secret_key_t *key,const BIGNUM *p, 76 const BIGNUM *q,const BIGNUM *d, 77 const BIGNUM *u,const BIGNUM *n, 78 const BIGNUM *e); 79 void ops_fast_create_rsa_secret_key(ops_secret_key_t *key,time_t time, 80 BIGNUM *p,BIGNUM *q,BIGNUM *d,BIGNUM *u, 81 BIGNUM *n,BIGNUM *e); 82 ops_boolean_t ops_write_struct_secret_key(const ops_secret_key_t *key, 83 ops_create_info_t *info); 84 92 85 #endif openpgpsdk/trunk/include/openpgpsdk/crypto.h
r279 r304 9 9 10 10 #define OPS_MAX_HASH 64 11 12 /** ops_hash_t */13 typedef struct _ops_hash_t ops_hash_t;14 11 15 12 typedef void ops_hash_init_t(ops_hash_t *hash); openpgpsdk/trunk/include/openpgpsdk/signature.h
r301 r304 5 5 #include "util.h" 6 6 #include "create.h" 7 8 /** \ingroup Create 9 * needed for signature creation 10 */ 11 typedef struct 12 { 13 ops_packet_writer_t *writer; /*!< The writer function */ 14 void *arg; /*!< Arguments for the writer function */ 15 ops_hash_t hash; 16 ops_signature_t sig; 17 ops_memory_t mem; 18 ops_create_info_t info; /*!< how to do the writing */ 19 unsigned hashed_count_offset; 20 unsigned hashed_data_length; 21 unsigned unhashed_count_offset; 22 } ops_create_signature_t; 7 23 8 24 ops_boolean_t … … 22 38 const ops_signature_t *sig, 23 39 const ops_public_key_t *signer); 24 void ops_signature_start(ops_create_signature_t *sig, 25 const ops_public_key_t *key, 26 const ops_user_id_t *id,ops_sig_type_t type); 40 void ops_signature_start_key_signature(ops_create_signature_t *sig, 41 const ops_public_key_t *key, 42 const ops_user_id_t *id, 43 ops_sig_type_t type); 44 void ops_signature_start_plaintext_signature(ops_create_signature_t *sig, 45 ops_hash_algorithm_t hash, 46 ops_sig_type_t type); 47 void ops_signature_add_data(ops_create_signature_t *sig,const void *buf, 48 size_t length); 27 49 void ops_signature_hashed_subpackets_end(ops_create_signature_t *sig); 28 50 void ops_write_signature(ops_create_signature_t *sig,ops_public_key_t *key, … … 33 55 void ops_signature_add_primary_user_id(ops_create_signature_t *sig, 34 56 ops_boolean_t primary); 35 openpgpsdk/trunk/include/openpgpsdk/types.h
r280 r304 24 24 /** ops_content_tag_t */ 25 25 typedef enum ops_content_tag_t ops_content_tag_t; 26 27 /** ops_hash_t */ 28 typedef struct _ops_hash_t ops_hash_t; 26 29 27 30 /** openpgpsdk/trunk/src/create.c
r302 r304 8 8 9 9 /* 10 * return 1 if OK, otherwise 011 */ 12 static int base_write(const void *src,unsigned length,13 ops_create_info_t *info)14 { 15 return info->writer(src,length,0,info ->arg) == OPS_W_OK;10 * return true if OK, otherwise false 11 */ 12 static ops_boolean_t base_write(const void *src,unsigned length, 13 ops_create_info_t *info) 14 { 15 return info->writer(src,length,0,info) == OPS_W_OK; 16 16 } 17 17 … … 202 202 /* not reached */ 203 203 return 0; 204 } 205 206 static unsigned secret_key_length(const ops_secret_key_t *key) 207 { 208 int l; 209 210 switch(key->public_key.algorithm) 211 { 212 case OPS_PKA_RSA: 213 l=mpi_length(key->key.rsa.d)+mpi_length(key->key.rsa.p) 214 +mpi_length(key->key.rsa.q)+mpi_length(key->key.rsa.u); 215 break; 216 217 default: 218 assert(!"unknown key algorithm"); 219 } 220 221 return l+public_key_length(&key->public_key); 204 222 } 205 223 … … 223 241 /* Note that we support v3 keys here because they're needed for 224 242 * for verification - the writer doesn't allow them, though */ 225 static int write_public_key_body(const ops_public_key_t *key,226 ops_create_info_t *info)243 static ops_boolean_t write_public_key_body(const ops_public_key_t *key, 244 ops_create_info_t *info) 227 245 { 228 246 if(!(ops_write_scalar(key->version,1,info) … … 264 282 } 265 283 284 static void push_secret_key_checksum_writer(ops_create_info_t *info) 285 { 286 OPS_USED(info); 287 // XXX: push a SHA-1 checksum writer (and change s2k to 254). 288 } 289 290 static ops_boolean_t pop_secret_key_checksum_writer(ops_create_info_t *info) 291 { 292 // XXX: actually write a SHA-1 checksum, but for now, dummy... 293 return ops_write_scalar(0,2,info); 294 } 295 296 297 /* Note that we support v3 keys here because they're needed for 298 * for verification - the writer doesn't allow them, though */ 299 static ops_boolean_t write_secret_key_body(const ops_secret_key_t *key, 300 ops_create_info_t *info) 301 { 302 if(!write_public_key_body(&key->public_key,info)) 303 return ops_false; 304 305 if(!ops_write_scalar(key->s2k_usage,1,info)) 306 return ops_false; 307 308 // XXX: for now, no secret key encryption, so s2k == 0 309 assert(key->s2k_usage == OPS_S2K_NONE); 310 311 push_secret_key_checksum_writer(info); 312 313 switch(key->public_key.algorithm) 314 { 315 // case OPS_PKA_DSA: 316 // return ops_write_mpi(key->key.dsa.x,info); 317 318 case OPS_PKA_RSA: 319 case OPS_PKA_RSA_ENCRYPT_ONLY: 320 case OPS_PKA_RSA_SIGN_ONLY: 321 if(!ops_write_mpi(key->key.rsa.d,info) 322 || !ops_write_mpi(key->key.rsa.p,info) 323 || !ops_write_mpi(key->key.rsa.q,info) 324 || !ops_write_mpi(key->key.rsa.u,info)) 325 return ops_false; 326 break; 327 328 // case OPS_PKA_ELGAMAL: 329 // return ops_write_mpi(key->key.elgamal.x,info); 330 331 default: 332 assert(0); 333 break; 334 } 335 336 return pop_secret_key_checksum_writer(info); 337 } 338 339 266 340 /** 267 341 * \ingroup Create … … 338 412 ops_memory_make_packet(out,OPS_PTAG_CT_PUBLIC_KEY); 339 413 } 414 415 /** 416 * \ingroup Create 417 * 418 * Create an RSA secret key structure. If a parameter is marked as 419 * [OPTIONAL], then it can be omitted and will be calculated from 420 * other parameters - or, in the case of e, will default to 0x10001. 421 * 422 * Parameters are _not_ copied, so will be freed if the structure is 423 * freed. 424 * 425 * \param key The key structure to be initialised. 426 * \param e The RSA parameter d (=e^-1 mod (p-1)(q-1)) [OPTIONAL] 427 * \param p The RSA parameter p 428 * \param q The RSA parameter q (q > p) 429 * \param u The RSA parameter u (=p^-1 mod q) [OPTIONAL] 430 * \param n The RSA public parameter n (=p*q) [OPTIONAL] 431 * \param e The RSA public parameter e */ 432 433 void ops_fast_create_rsa_secret_key(ops_secret_key_t *key,time_t time, 434 BIGNUM *d,BIGNUM *p,BIGNUM *q,BIGNUM *u, 435 BIGNUM *n,BIGNUM *e) 436 { 437 ops_fast_create_rsa_public_key(&key->public_key,time,n,e); 438 439 // XXX: calculate optionals 440 key->key.rsa.d=d; 441 key->key.rsa.p=p; 442 key->key.rsa.q=q; 443 key->key.rsa.u=u; 444 445 key->s2k_usage=OPS_S2K_NONE; 446 447 // XXX: sanity check and add errors... 448 } 449 450 /** 451 * \ingroup Create 452 * 453 * Writes a secret key. 454 * 455 * \param key The secret key 456 * \param info 457 * \return success 458 */ 459 ops_boolean_t ops_write_struct_secret_key(const ops_secret_key_t *key, 460 ops_create_info_t *info) 461 { 462 assert(key->public_key.version == 4); 463 464 return ops_write_ptag(OPS_PTAG_CT_SECRET_KEY,info) 465 && ops_write_length(1+4+1+1+secret_key_length(key)+2,info) 466 && write_secret_key_body(key,info); 467 } openpgpsdk/trunk/src/packet-parse.c
r299 r304 1683 1683 return 0; 1684 1684 C.secret_key.s2k_usage=c[0]; 1685 assert(C.secret_key.s2k_usage == 0);1685 assert(C.secret_key.s2k_usage == OPS_S2K_NONE); 1686 1686 1687 1687 switch(C.secret_key.public_key.algorithm) openpgpsdk/trunk/src/signature.c
r301 r304 127 127 } 128 128 129 static void common_init_signature(ops_hash_t *hash,const ops_signature_t *sig) 130 { 131 ops_hash_any(hash,sig->hash_algorithm); 132 hash->init(hash); 133 } 134 129 135 static void init_signature(ops_hash_t *hash,const ops_signature_t *sig, 130 136 const ops_public_key_t *key) 131 137 { 132 ops_hash_any(hash,sig->hash_algorithm); 133 hash->init(hash); 138 common_init_signature(hash,sig); 134 139 hash_add_key(hash,key); 135 140 } … … 290 295 * \ingroup Create 291 296 * 292 * ops_signature_start() creates a V4 signature with a SHA1 hash.297 * ops_signature_start() creates a V4 public key signature with a SHA1 hash. 293 298 * 294 * \param sig 295 * \param key 296 * \param id 297 * \param type 298 * \todo Expand description. 299 */ 300 void ops_signature_start(ops_create_signature_t *sig, 301 const ops_public_key_t *key, 302 const ops_user_id_t *id, 303 ops_sig_type_t type) 304 { 299 * \param sig The signature structure to initialise 300 * \param key The public key to be signed 301 * \param id The user ID being bound to the key 302 * \param type Signature type 303 * \todo Expand description. Allow other hashes. 304 */ 305 void ops_signature_start_key_signature(ops_create_signature_t *sig, 306 const ops_public_key_t *key, 307 const ops_user_id_t *id, 308 ops_sig_type_t type) 309 { 310 memset(sig,'\0',sizeof *sig); 305 311 // XXX: refactor with check (in several ways - check should probably 306 312 // use the buffered writer to construct packets (done), and also should … … 315 321 init_signature(&sig->hash,&sig->sig,key); 316 322 317 // \todo Fix this. user_id is UTF-8 so strlen may not work318 323 ops_hash_add_int(&sig->hash,0xb4,1); 319 324 ops_hash_add_int(&sig->hash,strlen((char *)id->user_id),4); … … 335 340 sig->hashed_count_offset=sig->mem.length; 336 341 ops_write_scalar(0,2,&sig->info); 342 } 343 344 /** 345 * \ingroup Create 346 * 347 * Create a V4 public key signature over some plaintext. 348 * 349 * \param sig The signature structure to initialise 350 * \param id 351 * \param type 352 * \todo Expand description. Allow other hashes. 353 */ 354 void ops_signature_start_plaintext_signature(ops_create_signature_t *sig, 355 ops_hash_algorithm_t hash, 356 ops_sig_type_t type) 357 { 358 memset(sig,'\0',sizeof *sig); 359 // XXX: refactor with check (in several ways - check should probably 360 // use the buffered writer to construct packets (done), and also should 361 // share code for hash calculation) 362 sig->sig.version=OPS_SIG_V4; 363 sig->sig.hash_algorithm=hash; 364 sig->sig.type=type; 365 366 sig->hashed_data_length=-1; 367 368 common_init_signature(&sig->hash,&sig->sig); 369 370 // since this has subpackets and stuff, we have to buffer the whole 371 // thing to get counts before writing. 372 ops_memory_init(&sig->mem,100); 373 sig->info.writer=ops_writer_memory; 374 sig->info.arg=&sig->mem; 375 376 // write nearly up to the first subpacket 377 ops_write_scalar(sig->sig.version,1,&sig->info); 378 ops_write_scalar(sig->sig.type,1,&sig->info); 379 ops_write_scalar(sig->sig.key_algorithm,1,&sig->info); 380 ops_write_scalar(sig->sig.hash_algorithm,1,&sig->info); 381 382 // dummy hashed subpacket count 383 sig->hashed_count_offset=sig->mem.length; 384 ops_write_scalar(0,2,&sig->info); 385 } 386 387 /** 388 * \ingroup Create 389 * 390 * Add plaintext data to a signature-to-be. 391 * 392 * \param sig The signature-to-be. 393 * \param buf The plaintext data. 394 * \param length The amount of plaintext data. 395 */ 396 void ops_signature_add_data(ops_create_signature_t *sig,const void *buf, 397 size_t length) 398 { 399 sig->hash.add(&sig->hash,buf,length); 337 400 } 338 401
