diff --git a/include/pcp/buffer.h b/include/pcp/buffer.h
index 737b7bb..61fe377 100644
--- a/include/pcp/buffer.h
+++ b/include/pcp/buffer.h
@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
- Copyright (C) 2014 T.v.Dein.
+ Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -69,7 +69,10 @@ void buffer_resize(Buffer *b, size_t len);
/* get some chunk of data from the buffer, starting from offset til len,
it doesn't allocate the returned data (void *buf, the 2nd argument).
*/
-size_t buffer_get(Buffer *b, void *buf, size_t len);
+size_t buffer_get_chunk(Buffer *b, void *buf, size_t len);
+
+/* return the whole buffer contents */
+unsigned char *buffer_get(Buffer *b);
/* same as buffer_get() but fetch some data chunk from somewhere
in the middle of the buffer */
diff --git a/include/pcp/key.h b/include/pcp/key.h
index c4bfe49..5d6faa9 100644
--- a/include/pcp/key.h
+++ b/include/pcp/key.h
@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
- Copyright (C) 2014 T.v.Dein.
+ Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,7 +38,6 @@
#include "uthash.h"
#include "jenhash.h"
#include "scrypt.h"
-#include "buffer.h"
/*
PCP private key structure. Most fields are self explanatory.
@@ -143,75 +142,6 @@ typedef struct _pcp_rec_t pcp_rec_t;
-/* RFC4880 alike public key export with some simplifications:
-
- In sig subpackets we're using fixed sized fields instead
- of the mess they use in rfc4880. Sorry. We use only these types:
-
- 2 = Signature Creation Time (4 byte)
- 3 = Signature Expiration Time (4 byte)
- 9 = Key Expiration Time (4 bytes)
- 20 = Notation Data (4 byte flags, N bytes name+value)
- 27 = Key Flags (1 byte, use 0x02, 0x08 and 0x80
-
- The actual signature field doesn't contain the 1st 16 bits
- of the hash, since crypto_sign() created signatures consist
- of the hash+signature anyway.
-
- So, a full pubkey export looks like this
-
- version
- ctime
- cipher
- 3 x raw keys \
- sigheader > calc hash from this
- sigsubs (header+data) /
- hash
- signature
-
- We use big-endian always.
-
- http://tools.ietf.org/html/rfc4880#section-5.2.3
-
- */
-struct _pcp_rfc_pubkey_header_t {
- uint8_t version;
- uint32_t ctime;
- uint8_t cipher;
-};
-
-struct _pcp_rfc_pubkey_0x21_t {
- byte sig_ed25519_pub[crypto_sign_PUBLICKEYBYTES];
- byte ed25519_pub[crypto_sign_PUBLICKEYBYTES];
- byte curve25519_pub[crypto_box_PUBLICKEYBYTES];
-};
-
-struct _pcp_rfc_pubkey_sigheader_0x21_t {
- uint8_t version;
- uint8_t type; /* 0x1F only, self signed */
- uint8_t pkcipher;
- uint8_t hashcipher;
- uint16_t numsubs;
-};
-
-struct _pcp_rfc_pubkey_sigsub_0x21_t {
- uint32_t size;
- uint8_t type;
-};
-
-struct _pcp_rfc_pubkey_sig_0x21_t {
- byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES];
-};
-
-typedef struct _pcp_rfc_pubkey_header_t rfc_pub_h;
-typedef struct _pcp_rfc_pubkey_0x21_t rfc_pub_k;
-typedef struct _pcp_rfc_pubkey_sigheader_0x21_t rfc_pub_sig_h;
-typedef struct _pcp_rfc_pubkey_sigsub_0x21_t rfc_pub_sig_s;
-typedef struct _pcp_rfc_pubkey_sig_0x21_t rfc_pub_sig;
-
-
-
-
void pcp_cleanhashes();
pcp_key_t *pcpkey_new ();
@@ -256,4 +186,5 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key);
int pcp_sanitycheck_key(pcp_key_t *key);
+
#endif /* _HAVE_PCP_KEYPAIR_H */
diff --git a/include/pcp/mgmt.h b/include/pcp/mgmt.h
new file mode 100644
index 0000000..be2a3b1
--- /dev/null
+++ b/include/pcp/mgmt.h
@@ -0,0 +1,134 @@
+/*
+ This file is part of Pretty Curved Privacy (pcp1).
+
+ Copyright (C) 2014 T.v.Dein.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ You can contact me by mail: .
+*/
+
+
+#ifndef _HAVE_PCP_MGMT_H
+#define _HAVE_PCP_MGMT_H
+
+#include
+#include
+#include
+#include
+
+#include "defines.h"
+#include "platform.h"
+#include "mem.h"
+#include "ed.h"
+#include "key.h"
+#include "buffer.h"
+
+
+
+
+/* RFC4880 alike public key export with some simplifications:
+
+ In sig subpackets we're using fixed sized fields instead
+ of the mess they use in rfc4880. Sorry. We use only these types:
+
+ 2 = Signature Creation Time (4 byte)
+ 3 = Signature Expiration Time (4 byte)
+ 9 = Key Expiration Time (4 bytes)
+ 20 = Notation Data (4 byte flags, N bytes name+value)
+ 27 = Key Flags (1 byte, use 0x02, 0x08 and 0x80
+
+ The actual signature field doesn't contain the 1st 16 bits
+ of the hash, since crypto_sign() created signatures consist
+ of the hash+signature anyway.
+
+ So, a full pubkey export looks like this
+
+ version
+ ctime
+ cipher
+ 3 x raw keys \
+ sigheader > calc hash from this
+ sigsubs (header+data) /
+ hash
+ signature
+
+ We use big-endian always.
+
+ http://tools.ietf.org/html/rfc4880#section-5.2.3
+
+ */
+struct _pcp_rfc_pubkey_header_t {
+ uint8_t version;
+ uint32_t ctime;
+ uint8_t cipher;
+};
+
+struct _pcp_rfc_pubkey_0x21_t {
+ byte sig_ed25519_pub[crypto_sign_PUBLICKEYBYTES];
+ byte ed25519_pub[crypto_sign_PUBLICKEYBYTES];
+ byte curve25519_pub[crypto_box_PUBLICKEYBYTES];
+};
+
+struct _pcp_rfc_pubkey_sigheader_0x21_t {
+ uint8_t version;
+ uint8_t type;
+ uint8_t pkcipher;
+ uint8_t hashcipher;
+ uint16_t numsubs;
+};
+
+struct _pcp_rfc_pubkey_sigsub_0x21_t {
+ uint32_t size;
+ uint8_t type;
+};
+
+struct _pcp_rfc_pubkey_sig_0x21_t {
+ byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES];
+};
+
+typedef struct _pcp_rfc_pubkey_header_t rfc_pub_h;
+typedef struct _pcp_rfc_pubkey_0x21_t rfc_pub_k;
+typedef struct _pcp_rfc_pubkey_sigheader_0x21_t rfc_pub_sig_h;
+typedef struct _pcp_rfc_pubkey_sigsub_0x21_t rfc_pub_sig_s;
+typedef struct _pcp_rfc_pubkey_sig_0x21_t rfc_pub_sig;
+
+#define EXP_PK_CIPHER 0x21
+#define EXP_PK_CIPHER_NAME "CURVE25519-ED25519-POLY1305-SALSA20"
+
+#define EXP_HASH_CIPHER 0x22
+#define EXP_HASH_NAME "BLAKE2"
+
+#define EXP_SIG_CIPHER 0x23
+#define EXP_SIG_CIPHER_NAME "ED25519"
+
+#define EXP_SIG_VERSION 0x01
+#define EXP_SIG_TYPE 0x1F /* self signed */
+
+/* sig sub notiation we support */
+#define EXP_SIG_SUB_CTIME 2
+#define EXP_SIG_SUB_SIGEXPIRE 3
+#define EXP_SIG_SUB_KEYEXPIRE 9
+#define EXP_SIG_SUB_NOTATION 20
+#define EXP_SIG_SUB_KEYFLAGS 27
+
+/* in armored mode, we're using the usual head+foot */
+#define EXP_PK_HEADER "-----BEGIN ED25519-CURVE29915 PUBLIC KEY-----"
+#define EXP_PK_FOOTER "------END ED25519-CURVE29915 PUBLICKEY------"
+
+
+/* export public key */
+Buffer *pcp_get_rfc_pub (pcp_pubkey_t *key, pcp_key_t *sk);
+
+#endif // _HAVE_PCP_MGMT_H
diff --git a/libpcp/buffer.c b/libpcp/buffer.c
index 6df481c..4af89e3 100644
--- a/libpcp/buffer.c
+++ b/libpcp/buffer.c
@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
- Copyright (C) 2014 T.v.Dein.
+ Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -65,7 +65,14 @@ void buffer_resize(Buffer *b, size_t len) {
}
}
-size_t buffer_get(Buffer *b, void *buf, size_t len) {
+unsigned char *buffer_get(Buffer *b) {
+ if(b->end > 0)
+ return b->buf;
+ else
+ return NULL;
+}
+
+size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
if(len > b->end - b->offset || len == 0) {
fatal("[buffer %s] attempt to read %ld data from buffer with size %ld %p at offset %ld",
len, b->size, b->offset);
diff --git a/libpcp/crypto.c b/libpcp/crypto.c
index 95775bf..3664f27 100644
--- a/libpcp/crypto.c
+++ b/libpcp/crypto.c
@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
- Copyright (C) 2013 T.Linden.
+ Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
- You can contact me by mail: .
+ You can contact me by mail: .
*/
diff --git a/libpcp/key.c b/libpcp/key.c
index 1dc178a..d63ed7f 100644
--- a/libpcp/key.c
+++ b/libpcp/key.c
@@ -1,7 +1,7 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
- Copyright (C) 2013 T.Linden.
+ Copyright (C) 2013-2014 T.v.Dein.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
- You can contact me by mail: .
+ You can contact me by mail: .
*/
@@ -394,70 +394,3 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
return 0;
}
-
-int pcp_get_rfc_pub (pcp_pubkey_t *key) {
- Buffer *out = buffer_new(1024, "bo1");
- Buffer *raw = buffer_new(1024, "bs1");
-
- /* add the header */
- buffer_add8(out, PCP_KEY_VERSION);
- buffer_add32(out, key->ctime);
- buffer_add8(out, PCP_RFC_CIPHER);
-
- /* add the keys */
- buffer_add(raw, key->edpub, 32);
- buffer_add(raw, key->edpub, 32);
- buffer_add(raw, key->pub, 32);
-
- /* add the sig header */
- buffer_add8(raw, PCP_KEY_VERSION);
- buffer_add8(raw, 0x1F); // FIXME: define
- buffer_add8(raw, PCP_RFC_CIPHER);
- buffer_add8(raw, PCP_RFC_CIPHER);
- buffer_add16(raw, 5);
-
- /* add sig ctime */
- buffer_add32be(raw, 4);
- buffer_add8(raw, 2);
- buffer_add32be(raw, time(0));
-
- /* add sig expire time */
- buffer_add32be(raw, 4);
- buffer_add8(raw, 3);
- buffer_add32be(raw, time(0) + 31536000);
-
- /* add key expire time */
- buffer_add32be(raw, 4);
- buffer_add8(raw, 9);
- buffer_add32be(raw, key->ctime);
-
- /* add name */
- size_t notation_size = strlen(key->owner) + 4 + 5;
- buffer_add32be(raw, notation_size);
- buffer_add8(raw, 20);
- buffer_add16be(raw, 5);
- buffer_add16be(raw, strlen(key->owner));
- buffer_add(raw, "owner", 5);
- buffer_add(raw, key->owner, strlen(key->owner));
-
- /* add mail */
- notation_size = strlen(key->mail) + 4 + 4;
- buffer_add32be(raw, notation_size);
- buffer_add8(raw, 20);
- buffer_add16be(raw, 4);
- buffer_add16be(raw, strlen(key->mail));
- buffer_add(raw, "mail", 4);
- buffer_add(raw, key->mail, strlen(key->mail));
-
- /* add key flags */
- buffer_add32be(raw, 1);
- buffer_add8(raw, 27);
- buffer_add8(raw, 0x02 & 0x08 & 0x80);
-
- /* FIXME:
- Now, calculate the signature from the raw buffer,
- add it to the output buffer, add the sig to the
- output buffer and finally return it. */
-
- return 0;
-}
diff --git a/libpcp/mgmt.c b/libpcp/mgmt.c
new file mode 100644
index 0000000..c5c3ad0
--- /dev/null
+++ b/libpcp/mgmt.c
@@ -0,0 +1,110 @@
+/*
+ This file is part of Pretty Curved Privacy (pcp1).
+
+ Copyright (C) 2013-2014 T.v.Dein.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ You can contact me by mail: .
+*/
+
+
+#include "mgmt.h"
+
+
+Buffer *pcp_get_rfc_pub (pcp_pubkey_t *key, pcp_key_t *sk) {
+ Buffer *out = buffer_new(320, "bo1");
+ Buffer *raw = buffer_new(256, "bs1");
+
+ /* add the header */
+ buffer_add8(out, PCP_KEY_VERSION);
+ buffer_add32(out, key->ctime);
+ buffer_add8(out, EXP_PK_CIPHER);
+
+ /* add the keys */
+ buffer_add(raw, key->edpub, 32);
+ buffer_add(raw, key->edpub, 32);
+ buffer_add(raw, key->pub, 32);
+
+ /* add the sig header */
+ buffer_add8(raw, EXP_SIG_VERSION);
+ buffer_add8(raw, EXP_SIG_TYPE);
+ buffer_add8(raw, EXP_SIG_CIPHER);
+ buffer_add8(raw, EXP_HASH_CIPHER);
+ buffer_add16(raw, 5); /* we add 5 sub sigs always */
+
+ /* add sig ctime */
+ buffer_add32be(raw, 4);
+ buffer_add8(raw, EXP_SIG_SUB_CTIME);
+ buffer_add32be(raw, time(0));
+
+ /* add sig expire time */
+ buffer_add32be(raw, 4);
+ buffer_add8(raw, EXP_SIG_SUB_SIGEXPIRE);
+ buffer_add32be(raw, time(0) + 31536000);
+
+ /* add key expire time */
+ buffer_add32be(raw, 4);
+ buffer_add8(raw, EXP_SIG_SUB_KEYEXPIRE);
+ buffer_add32be(raw, key->ctime + 31536000);
+
+ /* add name notation sub*/
+ size_t notation_size = strlen(key->owner) + 4 + 5;
+ buffer_add32be(raw, notation_size);
+ buffer_add8(raw, EXP_SIG_SUB_NOTATION);
+ buffer_add16be(raw, 5);
+ buffer_add16be(raw, strlen(key->owner));
+ buffer_add(raw, "owner", 5);
+ buffer_add(raw, key->owner, strlen(key->owner));
+
+ /* add mail notation sub */
+ notation_size = strlen(key->mail) + 4 + 4;
+ buffer_add32be(raw, notation_size);
+ buffer_add8(raw, EXP_SIG_SUB_NOTATION);
+ buffer_add16be(raw, 4);
+ buffer_add16be(raw, strlen(key->mail));
+ buffer_add(raw, "mail", 4);
+ buffer_add(raw, key->mail, strlen(key->mail));
+
+ /* add key flags */
+ buffer_add32be(raw, 1);
+ buffer_add8(raw, 27);
+ buffer_add8(raw, 0x02 & 0x08 & 0x80);
+
+ /* create a hash from the PK material and the raw signature packet */
+ crypto_generichash_state *st = ucmalloc(sizeof(crypto_generichash_state));
+ unsigned char *hash = ucmalloc(crypto_generichash_BYTES_MAX);
+
+ crypto_generichash_init(st, NULL, 0, 0);
+ crypto_generichash_update(st, buffer_get(raw), buffer_size(raw));
+ crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
+
+ /* sign the hash */
+ unsigned char *sig = pcp_ed_sign(hash, crypto_generichash_BYTES_MAX, sk->secret);
+
+ /* append the signature packet to the output */
+ buffer_add(out, buffer_get(raw), buffer_size(raw));
+
+ /* append the signed hash */
+ buffer_add(out, sig, crypto_generichash_BYTES_MAX + crypto_generichash_BYTES_MAX);
+
+ /* and that's it. wasn't that easy? :) */
+ buffer_free(raw);
+ memset(hash, 0, crypto_generichash_BYTES_MAX);
+ free(hash);
+ memset(sig, 0, crypto_generichash_BYTES_MAX + crypto_generichash_BYTES_MAX);
+ free(sig);
+
+ return out;
+}
diff --git a/src/keymgmt.c b/src/keymgmt.c
index 8283d23..4fccf77 100644
--- a/src/keymgmt.c
+++ b/src/keymgmt.c
@@ -336,7 +336,7 @@ int pcp_importsecret (vault_t *vault, FILE *in) {
}
if(clen != PCP_RAW_KEYSIZE) {
- fatal("Error: decoded input didn't result to a proper sized key! (got %d bytes)\n", clen);
+ fatal("Error: decoded input didn't result to a proper sized key! (got %ld bytes, expected %ld)\n", clen, PCP_RAW_KEYSIZE);
free(z85decoded);
return 1;
}
@@ -624,3 +624,69 @@ char *pcp_find_id_byrec(char *recipient) {
return id;
}
+
+
+/*
+ Experimental RFC4880-alike public key export. Once stable and
+ flexible enough, this will become the PCP default, I hope. */
+void pcp_exportpublic2(char *passwd, char *outfile, int armor) {
+ pcp_pubkey_t *key = NULL;
+
+ pcp_key_t *s = NULL;
+ s = pcp_find_primary_secret();
+ if(s == NULL) {
+ fatal("There's no primary secret key in the vault %s!\n", vault->filename);
+ free(s);
+ }
+ else {
+ key = pcpkey_pub_from_secret(s);
+ }
+
+ if(key != NULL) {
+ FILE *out;
+ if(outfile == NULL) {
+ out = stdout;
+ }
+ else {
+ if((out = fopen(outfile, "wb+")) == NULL) {
+ fatal("Could not create output file %s", outfile);
+ out = NULL;
+ }
+ }
+
+ if(out != NULL) {
+ pcp_key_t *sk = pcp_find_primary_secret();
+ if(sk != NULL) {
+ char *passphrase;
+ pcp_readpass(&passphrase, "Enter passphrase to decrypt your secret key for signing the export", NULL, 1);
+
+ sk = pcpkey_decrypt(sk, passphrase);
+ if(sk != NULL) {
+ Buffer *exported_pk = pcp_get_rfc_pub(key, sk);
+ if(exported_pk != NULL) {
+ if(armor == 1) {
+ size_t zlen;
+ char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen);
+ fprintf(out, "%s\r\n%s\r\n%s\r\n", EXP_PK_HEADER, z85, EXP_PK_FOOTER);
+ free(z85);
+ }
+ else
+ fwrite(buffer_get(exported_pk), 1, buffer_size(exported_pk), out);
+
+ fclose(out);
+ if(debug) {
+ buffer_dump(exported_pk);
+ buffer_info(exported_pk);
+ pcp_dumppubkey(key);
+ }
+ buffer_free(exported_pk);
+ }
+ }
+
+ free(passphrase);
+ }
+
+ free(key);
+ }
+ }
+}
diff --git a/src/keymgmt.h b/src/keymgmt.h
index 49af972..f0d72e7 100644
--- a/src/keymgmt.h
+++ b/src/keymgmt.h
@@ -40,6 +40,8 @@
#include "keyhash.h"
#include "util.h"
#include "base85.h"
+#include "buffer.h"
+#include "mgmt.h"
#define _WITH_GETLINE
@@ -58,4 +60,7 @@ int pcp_importsecret (vault_t *vault, FILE *in);
void pcpdelete_key(char *keyid);
char *pcp_find_id_byrec(char *recipient);
+/* Experimental: new rfc4880 style pk export */
+void pcp_exportpublic2(char *passwd, char *outfile, int armor);
+
#endif /* _HAVE_KEYMGMT_H */
diff --git a/src/pcp.c b/src/pcp.c
index 04dd714..b0eddbc 100644
--- a/src/pcp.c
+++ b/src/pcp.c
@@ -46,7 +46,7 @@ char *default_vault() {
}
int main (int argc, char **argv) {
- int opt, mode, usevault, useid, userec, lo, armor, detach, signcrypt, pbpcompat;
+ int opt, mode, usevault, useid, userec, lo, armor, detach, signcrypt, pbpcompat, rfc;
char *vaultfile = default_vault();
char *outfile = NULL;
char *infile = NULL;
@@ -70,6 +70,7 @@ int main (int argc, char **argv) {
detach = 0;
signcrypt = 0;
pbpcompat = 0;
+ rfc = 0;
static struct option longopts[] = {
/* generics */
@@ -92,6 +93,7 @@ int main (int argc, char **argv) {
{ "edit-key", no_argument, NULL, 'E' },
{ "export-yaml", no_argument, NULL, 'y' },
{ "pbpcompat", no_argument, NULL, 'b' },
+ { "rfc-format", no_argument, NULL, '1' }, /* no short option */
/* crypto */
{ "encrypt", no_argument, NULL, 'e' },
@@ -114,7 +116,7 @@ int main (int argc, char **argv) {
{ NULL, 0, NULL, 0 }
};
- while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPRtEx:DzZr:gcymf:b",
+ while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPRtEx:DzZr:gcymf:b1",
longopts, NULL)) != -1) {
switch (opt) {
@@ -151,6 +153,9 @@ int main (int argc, char **argv) {
mode += PCP_MODE_IMPORT_SECRET;
usevault = 1;
break;
+ case '1':
+ rfc = 1;
+ break;
case 'R':
mode += PCP_MODE_DELETE_KEY;
usevault = 1;
@@ -372,19 +377,24 @@ int main (int argc, char **argv) {
break;
case PCP_MODE_EXPORT_PUBLIC:
- if(useid) {
- id = pcp_normalize_id(keyid);
- if(id == NULL)
- break;
+ if(rfc) {
+ pcp_exportpublic2(xpass, outfile, armor);
+ }
+ else {
+ if(useid) {
+ id = pcp_normalize_id(keyid);
+ if(id == NULL)
+ break;
+ }
+ if (recipient != NULL)
+ pcp_exportpublic(id, recipient->value, xpass, outfile, pbpcompat);
+ else
+ pcp_exportpublic(id, NULL, xpass, outfile, pbpcompat);
+ if(xpass != NULL)
+ free(xpass);
+ if(recipient != NULL)
+ free(recipient);
}
- if (recipient != NULL)
- pcp_exportpublic(id, recipient->value, xpass, outfile, pbpcompat);
- else
- pcp_exportpublic(id, NULL, xpass, outfile, pbpcompat);
- if(xpass != NULL)
- free(xpass);
- if(recipient != NULL)
- free(recipient);
break;
case PCP_MODE_IMPORT_PUBLIC: