netpgp_save_pubring (ok), netpgp_save_secring (broken), raw initial key packet for generated keys

master
Edouard Tisserant 8 years ago
parent 711fd28093
commit 21d96a82f2

@ -78,7 +78,8 @@ int netpgp_list_keys_json(netpgp_t *, char **, const int);
int netpgp_find_key(netpgp_t *, char *);
char *netpgp_get_key(netpgp_t *, const char *, const char *);
char *netpgp_export_key(netpgp_t *, char *);
int netpgp_save_pubkeys(netpgp_t *);
int netpgp_save_secring(netpgp_t *);
int netpgp_save_pubring(netpgp_t *);
int netpgp_import_key(netpgp_t *, char *);
int netpgp_generate_key(netpgp_t *, char *, int);

@ -479,8 +479,8 @@ write_seckey_body(const pgp_seckey_t *key,
* \param output
* \return 1 if OK, otherwise 0
*/
static unsigned
write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
unsigned
pgp_write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
{
return pgp_write_ptag(output, PGP_PTAG_CT_PUBLIC_KEY) &&
pgp_write_length(output, 1 + 4 + 1 + pubkey_length(key)) &&
@ -510,7 +510,7 @@ pgp_write_xfer_pubkey(pgp_output_t *output,
pgp_writer_push_armoured(output, PGP_PGP_PUBLIC_KEY_BLOCK);
}
/* public key */
if (!write_struct_pubkey(output, &key->key.pubkey)) {
if (!pgp_write_struct_pubkey(output, &key->key.pubkey)) {
return 0;
}
@ -620,7 +620,7 @@ pgp_write_rsa_pubkey(time_t t, const BIGNUM *n,
pgp_pubkey_t key;
pgp_fast_create_rsa_pubkey(&key, t, __UNCONST(n), __UNCONST(e));
return write_struct_pubkey(output, &key);
return pgp_write_struct_pubkey(output, &key);
}
/**

@ -83,6 +83,7 @@ unsigned pgp_write_struct_seckey(const pgp_seckey_t *,
const uint8_t *,
const size_t,
pgp_output_t *);
unsigned pgp_write_struct_pubkey(pgp_output_t *, const pgp_pubkey_t *);
unsigned pgp_write_one_pass_sig(pgp_output_t *,
const pgp_seckey_t *,
const pgp_hash_alg_t,

@ -209,6 +209,14 @@ pgp_key_t *pgp_rsa_new_selfsign_key(const int,
const unsigned long, uint8_t *, const char *,
const char *);
unsigned pgp_rsa_generate_keypair(pgp_key_t *,
const int,
const unsigned long,
const char *,
const char *,
const uint8_t *,
const size_t);
int pgp_dsa_size(const pgp_dsa_pubkey_t *);
DSA_SIG *pgp_dsa_sign(uint8_t *, unsigned,
const pgp_dsa_seckey_t *,

@ -136,15 +136,71 @@ pgp_keydata_free(pgp_key_t *keydata)
keydata->packets = NULL;
keydata->packetc = 0;
/* XXX subsigs revokes ? */
if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
pgp_pubkey_free(&keydata->key.pubkey);
} else {
pgp_seckey_free(&keydata->key.seckey);
}
/* XXX sigkey enckey ? */
free(keydata);
}
int
pgp_keydata_dup(pgp_key_t *dst, pgp_key_t *src, unsigned make_public)
{
unsigned n;
int res = 0;
unsigned pktcpyof = 0;
memcpy(dst, src, sizeof(pgp_key_t));
if (src->type == PGP_PTAG_CT_PUBLIC_KEY) {
res = pgp_pubkey_dup(&dst->key.pubkey, &src->key.pubkey);
} else if (make_public && (
res = pgp_pubkey_dup(&dst->key.pubkey,
&src->key.seckey.pubkey))) {
pgp_output_t *output = NULL;
pgp_memory_t *mem = NULL;
dst->type = PGP_PTAG_CT_PUBLIC_KEY;
/* update first packet to reflect change in key type */
pgp_setup_memory_write(&output, &mem, 128);
if (pgp_write_struct_pubkey(output, &dst->key.pubkey)) {
pgp_subpacket_t pubkeypacket;
pubkeypacket.length = pgp_mem_len(mem);
pubkeypacket.raw = pgp_mem_data(mem);
pgp_add_subpacket(dst, &pubkeypacket);
pktcpyof++;
res = 1;
}
pgp_writer_close(output);
pgp_teardown_memory_write(output, mem);
} else {
res = pgp_seckey_dup(&dst->key.seckey, &src->key.seckey);
}
/* TODO sigkey enckey ? */
for (n = pktcpyof; n < src->packetc; ++n) {
pgp_add_subpacket(dst,&src->packets[n]);
}
for (n = 0; n < src->uidc; ++n) {
pgp_add_userid(dst,src->uids[n]);
}
/* TODO subsigs revokes ? */
return res;
}
/**
\ingroup HighLevel_KeyGeneral
@ -276,7 +332,7 @@ decrypt_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
return PGP_FINISHED;
}
decrypt->seckey->checkhash = calloc(1, PGP_CHECKHASH_SIZE);
*decrypt->seckey = content->seckey;
*decrypt->seckey = content->seckey; /* XXX WTF ? */
return PGP_KEEP_MEMORY;
case PGP_PARSER_PACKET_END:
@ -480,6 +536,21 @@ pgp_add_subpacket(pgp_key_t *keydata, const pgp_subpacket_t *packet)
return copy_packet(subpktp, packet);
}
pgp_subpacket_t *
pgp_replace_subpacket(
pgp_key_t *keydata,
const pgp_subpacket_t *packet,
unsigned index)
{
pgp_subpacket_t *subpktp;
if (keydata->packetc > index) {
subpktp = &keydata->packets[index];
pgp_subpacket_free(subpktp);
return copy_packet(subpktp, packet);
}
return NULL;
}
/**
\ingroup Core_Keys
\brief Add selfsigned User ID to key
@ -492,19 +563,30 @@ pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid)
{
pgp_create_sig_t *sig;
pgp_subpacket_t sigpacket;
pgp_subpacket_t useridpacket;
pgp_memory_t *mem_userid = NULL;
pgp_output_t *useridoutput = NULL;
pgp_memory_t *mem_sig = NULL;
pgp_output_t *sigoutput = NULL;
/*
* create signature packet for this userid
*/
/* add userid to key */
(void) pgp_add_userid(key, userid);
/* create userid pkt */
pgp_setup_memory_write(&useridoutput, &mem_userid, 128);
pgp_write_struct_userid(useridoutput, userid);
/* set packet content */
useridpacket.length = pgp_mem_len(mem_userid);
useridpacket.raw = pgp_mem_data(mem_userid);
/* add userid pkt to key */
(void) pgp_add_subpacket(key, &useridpacket);
/*
* create signature packet for this userid
*/
/* create sig for this pkt */
sig = pgp_create_sig_new();
pgp_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, PGP_CERT_POSITIVE);
@ -520,8 +602,7 @@ pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid)
sigpacket.length = pgp_mem_len(mem_sig);
sigpacket.raw = pgp_mem_data(mem_sig);
/* add userid to key */
(void) pgp_add_userid(key, userid);
/* add signature to key */
(void) pgp_add_subpacket(key, &sigpacket);
/* cleanup */

@ -85,6 +85,7 @@ const pgp_key_t *pgp_getnextkeybyname(pgp_io_t *,
const char *,
unsigned *);
void pgp_keydata_free(pgp_key_t *);
int pgp_keydata_dup(pgp_key_t *, pgp_key_t *, unsigned);
void pgp_keyring_free(pgp_keyring_t *);
void pgp_dump_keyring(const pgp_keyring_t *);
const pgp_pubkey_t *pgp_get_pubkey(const pgp_key_t *);
@ -110,6 +111,9 @@ unsigned pgp_is_key_supported(const pgp_key_t *);
uint8_t *pgp_add_userid(pgp_key_t *, const uint8_t *);
pgp_subpacket_t *pgp_add_subpacket(pgp_key_t *,
const pgp_subpacket_t *);
pgp_subpacket_t *pgp_replace_subpacket(pgp_key_t *,
const pgp_subpacket_t *,
unsigned );
unsigned pgp_add_selfsigned_userid(pgp_key_t *, uint8_t *);

@ -1144,61 +1144,66 @@ netpgp_export_key(netpgp_t *netpgp, char *name)
return pgp_export_key(io, key, NULL);
}
int
netpgp_save_pubkeys(netpgp_t *netpgp)
static int
netpgp_save_ring(netpgp_t *netpgp,
pgp_keyring_t *keyring,
char *name)
{
pgp_io_t *io;
pgp_key_t *key;
unsigned n;
pgp_keyring_t *keyring;
pgp_output_t *create;
int fd;
int err = 0;
char swpfile[MAXPATHLEN];
char backup[MAXPATHLEN];
char *ringfile;
int cur;
char *name = "pubkey";
time_t curtime;
io = netpgp->io;
pgp_io_t *io;
pgp_key_t *key;
unsigned n;
pgp_output_t *output;
int fd;
int err = 0;
char swpfile[MAXPATHLEN];
char backup[MAXPATHLEN];
char *ringfile;
int cur;
time_t curtime;
io = netpgp->io;
keyring = netpgp->pubring;
/* file names */
if ((ringfile = netpgp_getvar(netpgp, name)) == NULL) {
if ((ringfile = netpgp_getvar(netpgp, name)) == NULL) {
/* only save if already loaded by readkeyring(name) */
(void) fprintf(io->errs,
(void) fprintf(io->errs,
"netpgp_save_%s : No ring file defined\n", name);
return 0;
}
}
curtime = time(NULL);
if (snprintf(swpfile, sizeof(swpfile),
if (snprintf(swpfile, sizeof(swpfile),
"%s.swp", ringfile) >= sizeof(swpfile) ||
(cur = snprintf(backup, sizeof(backup),
"%s.backup_", ringfile)) >= sizeof(backup) ||
strftime(&backup[cur], sizeof(backup)-cur,
"%F.%T", localtime(&curtime)) >= sizeof(backup)-cur){
(void) fprintf(io->errs,
(void) fprintf(io->errs,
"netpgp_save_%s : file path too long\n", name);
return 0;
}
if ((fd = pgp_setup_file_write(&create, swpfile, 0)) < 0) {
(void) fprintf(io->errs,
unlink(swpfile);
if ((fd = pgp_setup_file_write(&output, swpfile, 0)) < 0) {
(void) fprintf(io->errs,
"netpgp_save_%s : can't setup write for %s\n", name, swpfile);
return 0;
}
return 0;
}
for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
if (!pgp_write_xfer_pubkey(create, key, 0 /* noarmor */)) {
err = 1;
(void) fprintf(io->errs,
"netpgp_save_%s : couldn't save key #%d\n", name, n);
break;
for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
/* Dump raw key packets to ring file */
unsigned j;
for (j = 0; j < key->packetc; j++) {
if (!pgp_write(output, key->packets[j].raw, (unsigned)key->packets[j].length)) {
err = 1;
(void) fprintf(io->errs,
"netpgp_save_%s : couldn't save key #%d\n", name, n);
break;
}
}
}
}
pgp_teardown_file_write(create, fd);
pgp_teardown_file_write(output, fd);
if(err){
unlink(swpfile);
@ -1208,7 +1213,19 @@ netpgp_save_pubkeys(netpgp_t *netpgp)
rename(ringfile, backup);
rename(swpfile, ringfile);
return 1;
return 1;
}
int
netpgp_save_pubring(netpgp_t *netpgp)
{
return netpgp_save_ring(netpgp, netpgp->pubring, "pubring");
}
int
netpgp_save_secring(netpgp_t *netpgp)
{
return netpgp_save_ring(netpgp, netpgp->secring, "secring");
}
#define IMPORT_ARMOR_HEAD "-----BEGIN PGP PUBLIC KEY BLOCK-----"

@ -681,12 +681,14 @@ pgp_text_from_hash(pgp_hash_t *hash)
\return 1 if key generated successfully; otherwise 0
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
*/
static unsigned
rsa_generate_keypair(pgp_key_t *keydata,
unsigned
pgp_rsa_generate_keypair(pgp_key_t *keydata,
const int numbits,
const unsigned long e,
const char *hashalg,
const char *cipher)
const char *cipher,
const uint8_t *passphrase,
const size_t pplen)
{
pgp_seckey_t *seckey;
RSA *rsa;
@ -773,6 +775,24 @@ 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;
}else{
pgp_subpacket_t seckeypacket;
seckeypacket.length = pgp_mem_len(mem);
seckeypacket.raw = pgp_mem_data(mem);
(void) pgp_add_subpacket(keydata, &seckeypacket);
}
pgp_writer_close(output);
pgp_teardown_memory_write(output, mem);
/* test */
if (pgp_get_debug_level(__FILE__)) {
test_seckey(seckey);
@ -790,7 +810,7 @@ rsa_generate_keypair(pgp_key_t *keydata,
\return The new keypair or NULL
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
\sa rsa_generate_keypair()
\sa pgp_rsa_generate_keypair()
\sa pgp_keydata_free()
*/
pgp_key_t *
@ -803,7 +823,8 @@ pgp_rsa_new_selfsign_key(const int numbits,
pgp_key_t *keydata;
keydata = pgp_keydata_new();
if (!rsa_generate_keypair(keydata, numbits, e, hashalg, cipher) ||
if (!pgp_rsa_generate_keypair(keydata, numbits, e, hashalg, cipher,
(const uint8_t *) "", (const size_t) 0) ||
!pgp_add_selfsigned_userid(keydata, userid)) {
pgp_keydata_free(keydata);
return NULL;

@ -920,6 +920,11 @@ free_BN(BIGNUM **pp)
*pp = NULL;
}
static void
dup_BN(BIGNUM **dst, BIGNUM **src)
{
*dst = BN_dup(*src);
}
/**
* \ingroup Core_Create
* \brief Free the memory used when parsing a signature
@ -1190,6 +1195,43 @@ pgp_pubkey_free(pgp_pubkey_t *p)
}
}
int
pgp_pubkey_dup(pgp_pubkey_t *dst, pgp_pubkey_t *src)
{
switch (src->alg) {
case PGP_PKA_RSA:
case PGP_PKA_RSA_ENCRYPT_ONLY:
case PGP_PKA_RSA_SIGN_ONLY:
dup_BN(&dst->key.rsa.n, &src->key.rsa.n);
dup_BN(&dst->key.rsa.e, &src->key.rsa.e);
break;
case PGP_PKA_DSA:
dup_BN(&dst->key.dsa.p, &src->key.dsa.p);
dup_BN(&dst->key.dsa.q, &src->key.dsa.q);
dup_BN(&dst->key.dsa.g, &src->key.dsa.g);
dup_BN(&dst->key.dsa.y, &src->key.dsa.y);
break;
case PGP_PKA_ELGAMAL:
case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
dup_BN(&dst->key.elgamal.p, &src->key.elgamal.p);
dup_BN(&dst->key.elgamal.g, &src->key.elgamal.g);
dup_BN(&dst->key.elgamal.y, &src->key.elgamal.y);
break;
case PGP_PKA_NOTHING:
/* nothing to dup */
break;
default:
(void) fprintf(stderr, "pgp_pubkey_dup: bad alg\n");
return 0;
}
/*TODO alloc error handling */
return 1;
}
/**
\ingroup Core_ReadPackets
*/
@ -2306,6 +2348,45 @@ pgp_seckey_free(pgp_seckey_t *key)
pgp_show_pka(key->pubkey.alg));
}
free(key->checkhash);
pgp_pubkey_free(&key->pubkey);
}
int
pgp_seckey_dup(pgp_seckey_t *dst, pgp_seckey_t *src)
{
switch (src->pubkey.alg) {
case PGP_PKA_RSA:
case PGP_PKA_RSA_ENCRYPT_ONLY:
case PGP_PKA_RSA_SIGN_ONLY:
dup_BN(&src->key.rsa.d, &src->key.rsa.d);
dup_BN(&src->key.rsa.p, &src->key.rsa.p);
dup_BN(&src->key.rsa.q, &src->key.rsa.q);
dup_BN(&src->key.rsa.u, &src->key.rsa.u);
break;
case PGP_PKA_DSA:
dup_BN(&src->key.dsa.x, &src->key.dsa.x);
break;
default:
(void) fprintf(stderr,
"pgp_seckey_dup: Unknown algorithm: %d (%s)\n",
src->pubkey.alg,
pgp_show_pka(src->pubkey.alg));
return 0;
}
if ((dst->checkhash = calloc(1, PGP_CHECKHASH_SIZE)) == NULL) {
(void) fprintf(stderr, "pgp_seckey_dup: bad alloc\n");
return 0;
}else{
memcpy(dst->checkhash, src->checkhash, PGP_CHECKHASH_SIZE);
}
pgp_pubkey_dup(&dst->pubkey, &src->pubkey);
/*TODO alloc error handling */
return 1;
}
static int

@ -884,6 +884,7 @@ int pgp_fingerprint(pgp_fingerprint_t *, const pgp_pubkey_t *, pgp_hash_alg_t);
void pgp_finish(void);
void pgp_pubkey_free(pgp_pubkey_t *);
int pgp_pubkey_dup(pgp_pubkey_t *,pgp_pubkey_t *);
void pgp_userid_free(uint8_t **);
void pgp_data_free(pgp_data_t *);
void pgp_sig_free(pgp_sig_t *);
@ -894,6 +895,7 @@ void pgp_ss_sig_target_free(pgp_ss_sig_target_t *);
void pgp_subpacket_free(pgp_subpacket_t *);
void pgp_parser_content_free(pgp_packet_t *);
void pgp_seckey_free(pgp_seckey_t *);
int pgp_seckey_dup(pgp_seckey_t *,pgp_seckey_t *);
void pgp_pk_sesskey_free(pgp_pk_sesskey_t *);
int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *);

Loading…
Cancel
Save