mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 12:00:56 +01:00
continue new pk-expoert format
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
134
include/pcp/mgmt.h
Normal file
134
include/pcp/mgmt.h
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tom AT vondein DOT org>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _HAVE_PCP_MGMT_H
|
||||
#define _HAVE_PCP_MGMT_H
|
||||
|
||||
#include <sodium.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#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
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tlinden AT cpan DOT org>.
|
||||
You can contact me by mail: <tom AT vondein DOT org>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
71
libpcp/key.c
71
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tlinden AT cpan DOT org>.
|
||||
You can contact me by mail: <tom AT vondein DOT org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
110
libpcp/mgmt.c
Normal file
110
libpcp/mgmt.c
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tom AT vondein DOT org>.
|
||||
*/
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
38
src/pcp.c
38
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:
|
||||
|
||||
Reference in New Issue
Block a user