diff --git a/dist/src/lib/create.c b/dist/src/lib/create.c index 47ff285..40c111e 100644 --- a/dist/src/lib/create.c +++ b/dist/src/lib/create.c @@ -301,154 +301,156 @@ write_seckey_body(const pgp_seckey_t *key, if (!write_pubkey_body(&key->pubkey, output)) { return 0; } - if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) { - (void) fprintf(stderr, "write_seckey_body: s2k usage\n"); - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) { - return 0; - } + if (key->s2k_usage != PGP_S2KU_NONE) { + if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) { + (void) fprintf(stderr, "write_seckey_body: s2k usage\n"); + return 0; + } + if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) { + return 0; + } - if (key->alg != PGP_SA_CAST5) { - (void) fprintf(stderr, "write_seckey_body: algorithm\n"); - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) { - return 0; - } + if (key->alg != PGP_SA_CAST5) { + (void) fprintf(stderr, "write_seckey_body: algorithm\n"); + return 0; + } + if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) { + return 0; + } - if (key->s2k_specifier != PGP_S2KS_SIMPLE && - key->s2k_specifier != PGP_S2KS_SALTED) { - /* = 1 \todo could also be iterated-and-salted */ - (void) fprintf(stderr, "write_seckey_body: s2k spec\n"); - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->s2k_specifier, 1)) { - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->hash_alg, 1)) { - return 0; - } + if (key->s2k_specifier != PGP_S2KS_SIMPLE && + key->s2k_specifier != PGP_S2KS_SALTED) { + /* = 1 \todo could also be iterated-and-salted */ + (void) fprintf(stderr, "write_seckey_body: s2k spec\n"); + return 0; + } + if (!pgp_write_scalar(output, (unsigned)key->s2k_specifier, 1)) { + return 0; + } + if (!pgp_write_scalar(output, (unsigned)key->hash_alg, 1)) { + return 0; + } - switch (key->s2k_specifier) { - case PGP_S2KS_SIMPLE: - /* nothing more to do */ - break; + switch (key->s2k_specifier) { + case PGP_S2KS_SIMPLE: + /* nothing more to do */ + break; - case PGP_S2KS_SALTED: - /* 8-octet salt value */ - pgp_random(__UNCONST(&key->salt[0]), PGP_SALT_SIZE); - if (!pgp_write(output, key->salt, PGP_SALT_SIZE)) { - return 0; - } - break; + case PGP_S2KS_SALTED: + /* 8-octet salt value */ + pgp_random(__UNCONST(&key->salt[0]), PGP_SALT_SIZE); + if (!pgp_write(output, key->salt, PGP_SALT_SIZE)) { + return 0; + } + break; - /* - * \todo case PGP_S2KS_ITERATED_AND_SALTED: // 8-octet salt - * value // 1-octet count break; - */ + /* + * \todo case PGP_S2KS_ITERATED_AND_SALTED: // 8-octet salt + * value // 1-octet count break; + */ - default: - (void) fprintf(stderr, - "invalid/unsupported s2k specifier %d\n", - key->s2k_specifier); - return 0; - } + default: + (void) fprintf(stderr, + "invalid/unsupported s2k specifier %d\n", + key->s2k_specifier); + return 0; + } - if (!pgp_write(output, &key->iv[0], pgp_block_size(key->alg))) { - return 0; - } + if (!pgp_write(output, &key->iv[0], pgp_block_size(key->alg))) { + return 0; + } - /* - * create the session key for encrypting the algorithm-specific - * fields - */ + /* + * create the session key for encrypting the algorithm-specific + * fields + */ - switch (key->s2k_specifier) { - case PGP_S2KS_SIMPLE: - case PGP_S2KS_SALTED: - /* RFC4880: section 3.7.1.1 and 3.7.1.2 */ - - for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) { - unsigned hashsize; - unsigned j; - unsigned needed; - unsigned size; - uint8_t zero = 0; - - /* Hard-coded SHA1 for session key */ - pgp_hash_any(&hash, PGP_HASH_SHA1); - hashsize = pgp_hash_size(key->hash_alg); - needed = CAST_KEY_LENGTH - done; - size = MIN(needed, hashsize); - if ((hashed = calloc(1, hashsize)) == NULL) { - (void) fprintf(stderr, "write_seckey_body: bad alloc\n"); - return 0; - } - if (!hash.init(&hash)) { - (void) fprintf(stderr, "write_seckey_body: bad alloc\n"); - return 0; - } + switch (key->s2k_specifier) { + case PGP_S2KS_SIMPLE: + case PGP_S2KS_SALTED: + /* RFC4880: section 3.7.1.1 and 3.7.1.2 */ + + for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) { + unsigned hashsize; + unsigned j; + unsigned needed; + unsigned size; + uint8_t zero = 0; + + /* Hard-coded SHA1 for session key */ + pgp_hash_any(&hash, PGP_HASH_SHA1); + hashsize = pgp_hash_size(key->hash_alg); + needed = CAST_KEY_LENGTH - done; + size = MIN(needed, hashsize); + if ((hashed = calloc(1, hashsize)) == NULL) { + (void) fprintf(stderr, "write_seckey_body: bad alloc\n"); + return 0; + } + if (!hash.init(&hash)) { + (void) fprintf(stderr, "write_seckey_body: bad alloc\n"); + return 0; + } - /* preload if iterating */ - for (j = 0; j < i; j++) { - /* - * Coverity shows a DEADCODE error on this - * line. This is expected since the hardcoded - * use of SHA1 and CAST5 means that it will - * not used. This will change however when - * other algorithms are supported. - */ - hash.add(&hash, &zero, 1); - } + /* preload if iterating */ + for (j = 0; j < i; j++) { + /* + * Coverity shows a DEADCODE error on this + * line. This is expected since the hardcoded + * use of SHA1 and CAST5 means that it will + * not used. This will change however when + * other algorithms are supported. + */ + hash.add(&hash, &zero, 1); + } - if (key->s2k_specifier == PGP_S2KS_SALTED) { - hash.add(&hash, key->salt, PGP_SALT_SIZE); - } - hash.add(&hash, passphrase, (unsigned)pplen); - hash.finish(&hash, hashed); - - /* - * if more in hash than is needed by session key, use - * the leftmost octets - */ - (void) memcpy(&sesskey[i * hashsize], - hashed, (unsigned)size); - done += (unsigned)size; - if (done > CAST_KEY_LENGTH) { - (void) fprintf(stderr, - "write_seckey_body: short add\n"); - return 0; - } - } + if (key->s2k_specifier == PGP_S2KS_SALTED) { + hash.add(&hash, key->salt, PGP_SALT_SIZE); + } + hash.add(&hash, passphrase, (unsigned)pplen); + hash.finish(&hash, hashed); + + /* + * if more in hash than is needed by session key, use + * the leftmost octets + */ + (void) memcpy(&sesskey[i * hashsize], + hashed, (unsigned)size); + done += (unsigned)size; + if (done > CAST_KEY_LENGTH) { + (void) fprintf(stderr, + "write_seckey_body: short add\n"); + return 0; + } + } - break; + break; - /* - * \todo case PGP_S2KS_ITERATED_AND_SALTED: * 8-octet salt - * value * 1-octet count break; - */ + /* + * \todo case PGP_S2KS_ITERATED_AND_SALTED: * 8-octet salt + * value * 1-octet count break; + */ - default: - (void) fprintf(stderr, - "invalid/unsupported s2k specifier %d\n", - key->s2k_specifier); - return 0; - } + default: + (void) fprintf(stderr, + "invalid/unsupported s2k specifier %d\n", + key->s2k_specifier); + return 0; + } - /* use this session key to encrypt */ + /* use this session key to encrypt */ - pgp_crypt_any(&crypted, key->alg); - crypted.set_iv(&crypted, key->iv); - crypted.set_crypt_key(&crypted, sesskey); - pgp_encrypt_init(&crypted); + pgp_crypt_any(&crypted, key->alg); + crypted.set_iv(&crypted, key->iv); + crypted.set_crypt_key(&crypted, sesskey); + pgp_encrypt_init(&crypted); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "writing: iv=", key->iv, pgp_block_size(key->alg)); - hexdump(stderr, "key= ", sesskey, CAST_KEY_LENGTH); - (void) fprintf(stderr, "\nturning encryption on...\n"); - } - pgp_push_enc_crypt(output, &crypted); + if (pgp_get_debug_level(__FILE__)) { + hexdump(stderr, "writing: iv=", key->iv, pgp_block_size(key->alg)); + hexdump(stderr, "key= ", sesskey, CAST_KEY_LENGTH); + (void) fprintf(stderr, "\nturning encryption on...\n"); + } + pgp_push_enc_crypt(output, &crypted); + } switch (key->pubkey.alg) { case PGP_PKA_RSA: @@ -477,7 +479,9 @@ write_seckey_body(const pgp_seckey_t *key, return 0; } - pgp_writer_pop(output); + if (key->s2k_usage != PGP_S2KU_NONE) { + pgp_writer_pop(output); + } return 1; } diff --git a/dist/src/lib/crypto.c b/dist/src/lib/crypto.c index 9bfc63e..b0c8d20 100644 --- a/dist/src/lib/crypto.c +++ b/dist/src/lib/crypto.c @@ -701,7 +701,7 @@ pgp_decrypt_and_validate_buf(pgp_io_t *io, validation.mem = pgp_memory_new(); pgp_memory_init(validation.mem, 128); - /* setup for writing decrypted contents to given output file */ + /* setup for writing decrypted contents */ pgp_setup_memory_write(&stream->cbinfo.output, &outmem, insize); /* setup keyring and passphrase callback */ diff --git a/dist/src/lib/keyring.c b/dist/src/lib/keyring.c index 3f785cf..3a22286 100644 --- a/dist/src/lib/keyring.c +++ b/dist/src/lib/keyring.c @@ -862,6 +862,40 @@ pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid) return 1; } +unsigned +pgp_key_revoke(pgp_key_t *key, uint8_t code, const char *reason) +{ + pgp_create_sig_t *sig; + pgp_subpacket_t sigpacket; + pgp_memory_t *mem_sig = NULL; + pgp_output_t *sigoutput = NULL; + + sig = pgp_create_sig_new(); + pgp_sig_start_key_rev( + sig, &key->key.seckey.pubkey, + PGP_SIG_REV_KEY); + + pgp_add_time(sig, (int64_t)time(NULL), "birth"); + pgp_add_issuer_keyid(sig, key->pubkeyid); + pgp_add_revocation_reason(sig, code, reason); + pgp_end_hashed_subpkts(sig); + + pgp_setup_memory_write(&sigoutput, &mem_sig, 128); + pgp_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey); + + sigpacket.length = pgp_mem_len(mem_sig); + sigpacket.raw = pgp_mem_data(mem_sig); + + pgp_add_directsig(key, &sigpacket, &sig->sig.info); + + /* cleanup */ + pgp_create_sig_delete(sig); + pgp_output_delete(sigoutput); + pgp_memory_free(mem_sig); + + return 1; +} + /** \ingroup Core_Keys \brief Initialise pgp_key_t diff --git a/dist/src/lib/keyring.h b/dist/src/lib/keyring.h index d0e2c61..3113a83 100644 --- a/dist/src/lib/keyring.h +++ b/dist/src/lib/keyring.h @@ -221,4 +221,7 @@ pgp_key_find_uid_cond( const pgp_key_rating_t pgp_key_get_rating(const pgp_key_t *key); +unsigned +pgp_key_revoke(pgp_key_t *key, uint8_t code, const char *reason); + #endif /* KEYRING_H_ */ diff --git a/dist/src/lib/openssl_crypto.c b/dist/src/lib/openssl_crypto.c index 192ea6c..e287ff9 100644 --- a/dist/src/lib/openssl_crypto.c +++ b/dist/src/lib/openssl_crypto.c @@ -601,7 +601,7 @@ pgp_rsa_private_decrypt(uint8_t *out, ERR_error_string(err, &errbuf[0]); (void) fprintf(stderr, "openssl error : %s\n", errbuf); } - keypair->n = keypair->d = keypair->p = keypair->q = NULL; + keypair->n = keypair->e = keypair->d = keypair->p = keypair->q = NULL; RSA_free(keypair); return n; @@ -712,10 +712,13 @@ pgp_rsa_generate_keypair(pgp_key_t *keydata, seckey->pubkey.alg = PGP_PKA_RSA; seckey->pubkey.key.rsa.n = BN_dup(rsa->n); + printf("RSA N %p %d\n", seckey->pubkey.key.rsa.n, BN_num_bits(seckey->pubkey.key.rsa.n)); seckey->pubkey.key.rsa.e = BN_dup(rsa->e); + printf("RSA E %p %d\n", seckey->pubkey.key.rsa.e, BN_num_bits(seckey->pubkey.key.rsa.e)); - seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; - seckey->s2k_specifier = PGP_S2KS_SALTED; + /* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */ + seckey->s2k_usage = PGP_S2KU_NONE; + /* seckey->s2k_specifier = PGP_S2KS_SALTED;*/ /* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */ if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) { seckey->hash_alg = PGP_HASH_SHA1; @@ -775,19 +778,6 @@ pgp_rsa_generate_keypair(pgp_key_t *keydata, /* should now have checksum in seckey struct */ - /* add seckey raw packet */ - output = NULL; - mem = NULL; - - pgp_setup_memory_write(&output, &mem, 128); - - if (!pgp_write_struct_seckey(seckey, passphrase, pplen, output)) { - return 0; - } - - pgp_writer_close(output); - pgp_teardown_memory_write(output, mem); - /* test */ if (pgp_get_debug_level(__FILE__)) { test_seckey(seckey); diff --git a/dist/src/lib/signature.c b/dist/src/lib/signature.c index f2fd9c7..d8ffe94 100644 --- a/dist/src/lib/signature.c +++ b/dist/src/lib/signature.c @@ -645,6 +645,22 @@ pgp_sig_start_key_sig(pgp_create_sig_t *sig, start_sig_in_mem(sig); } +void +pgp_sig_start_key_rev(pgp_create_sig_t *sig, + const pgp_pubkey_t *key, + pgp_sig_type_t type) +{ + sig->output = pgp_output_new(); + + sig->sig.info.version = PGP_V4; + sig->sig.info.hash_alg = PGP_HASH_SHA1; + sig->sig.info.key_alg = key->alg; + sig->sig.info.type = type; + sig->hashlen = (unsigned)-1; + init_key_sig(&sig->hash, &sig->sig, key); + start_sig_in_mem(sig); +} + /** * \ingroup Core_Signature * @@ -873,6 +889,19 @@ pgp_add_primary_userid(pgp_create_sig_t *sig, unsigned primary) pgp_write_scalar(sig->output, primary, 1); } +unsigned +pgp_add_revocation_reason( + pgp_create_sig_t *sig, + uint8_t code, const char *reason) +{ + size_t rlen = strlen(reason); + return pgp_write_ss_header( + sig->output, rlen + 1, + PGP_PTAG_SS_REVOCATION_REASON) && + pgp_write_scalar(sig->output, code, 1) && + pgp_write(sig->output, reason, rlen); +} + /** * \ingroup Core_Signature * diff --git a/dist/src/lib/signature.h b/dist/src/lib/signature.h index 6c7e02a..f265dc5 100644 --- a/dist/src/lib/signature.h +++ b/dist/src/lib/signature.h @@ -172,4 +172,14 @@ struct pgp_create_sig_t { unsigned unhashoff; }; +void +pgp_sig_start_key_rev(pgp_create_sig_t *sig, + const pgp_pubkey_t *key, + pgp_sig_type_t type); + +unsigned +pgp_add_revocation_reason( + pgp_create_sig_t *sig, + uint8_t code, const char *reason); + #endif /* SIGNATURE_H_ */