mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 12:00:56 +01:00
moved the actual public key export code out into the lib (mgmt.c). cmdline client does only armor the blobs, if neccessary. Also, armored pubkey exports don't contain any comments anymore.
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
/* key management api, export, import, yaml and stuff */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -128,7 +129,15 @@ typedef struct _pcp_rfc_pubkey_sig_0x21_t rfc_pub_sig;
|
|||||||
#define EXP_PK_FOOTER "------END ED25519-CURVE29915 PUBLICKEY------"
|
#define EXP_PK_FOOTER "------END ED25519-CURVE29915 PUBLICKEY------"
|
||||||
|
|
||||||
|
|
||||||
|
/* pubkey export formats */
|
||||||
|
#define EXP_FORMAT_NATIVE 0x01
|
||||||
|
#define EXP_FORMAT_PBP 0x03
|
||||||
|
|
||||||
|
|
||||||
/* export public key */
|
/* export public key */
|
||||||
Buffer *pcp_get_rfc_pub (pcp_pubkey_t *key, pcp_key_t *sk);
|
Buffer *pcp_export_rfc_pub (pcp_key_t *sk);
|
||||||
|
|
||||||
|
/* export public key in pbp format */
|
||||||
|
Buffer *pcp_export_pbp_pub(pcp_key_t *sk);
|
||||||
|
|
||||||
#endif // _HAVE_PCP_MGMT_H
|
#endif // _HAVE_PCP_MGMT_H
|
||||||
|
|||||||
@@ -22,20 +22,72 @@
|
|||||||
|
|
||||||
#include "mgmt.h"
|
#include "mgmt.h"
|
||||||
|
|
||||||
|
Buffer *pcp_export_pbp_pub(pcp_key_t *sk) {
|
||||||
|
struct tm *v, *c;
|
||||||
|
unsigned char *signature = NULL;
|
||||||
|
char *date = NULL;
|
||||||
|
|
||||||
Buffer *pcp_get_rfc_pub (pcp_pubkey_t *key, pcp_key_t *sk) {
|
Buffer *out = buffer_new(320, "pbp01");
|
||||||
|
Buffer *sig = buffer_new(320, "pbsig01");
|
||||||
|
|
||||||
|
/* add raw key material */
|
||||||
|
buffer_add(sig, sk->edpub, crypto_sign_PUBLICKEYBYTES);
|
||||||
|
buffer_add(sig, sk->edpub, crypto_sign_PUBLICKEYBYTES);
|
||||||
|
buffer_add(sig, sk->pub, crypto_box_PUBLICKEYBYTES);
|
||||||
|
|
||||||
|
/* add creatioin and expire time as 32byte iso time string */
|
||||||
|
time_t t = (time_t)sk->ctime;
|
||||||
|
c = localtime(&t);
|
||||||
|
time_t vt = t + 31536000;
|
||||||
|
v = localtime(&vt);
|
||||||
|
date = ucmalloc(65);
|
||||||
|
sprintf(date, "%04d-%02d-%02dT%02d:%02d:%02d.000000 %04d-%02d-%02dT%02d:%02d:%02d.000000 ",
|
||||||
|
c->tm_year+1900-1, c->tm_mon+1, c->tm_mday, // wtf? why -1?
|
||||||
|
c->tm_hour, c->tm_min, c->tm_sec,
|
||||||
|
v->tm_year+1900-1, v->tm_mon+1, v->tm_mday,
|
||||||
|
v->tm_hour, v->tm_min, v->tm_sec);
|
||||||
|
buffer_add(sig, date, 64);
|
||||||
|
|
||||||
|
/* add owner */
|
||||||
|
buffer_add(sig, sk->owner, strlen(sk->owner));
|
||||||
|
|
||||||
|
/* calculate the signed key blob */
|
||||||
|
signature = pcp_ed_sign(buffer_get(sig), buffer_size(sig), sk);
|
||||||
|
|
||||||
|
if(signature == NULL)
|
||||||
|
goto exppbperr01;
|
||||||
|
|
||||||
|
/* put it out */
|
||||||
|
buffer_add_buf(out, sig);
|
||||||
|
|
||||||
|
free(date);
|
||||||
|
buffer_free(sig);
|
||||||
|
free(v);
|
||||||
|
return out;
|
||||||
|
|
||||||
|
|
||||||
|
exppbperr01:
|
||||||
|
buffer_free(sig);
|
||||||
|
buffer_free(out);
|
||||||
|
free(date);
|
||||||
|
free(v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
|
||||||
Buffer *out = buffer_new(320, "bo1");
|
Buffer *out = buffer_new(320, "bo1");
|
||||||
Buffer *raw = buffer_new(256, "bs1");
|
Buffer *raw = buffer_new(256, "bs1");
|
||||||
|
|
||||||
/* add the header */
|
/* add the header */
|
||||||
buffer_add8(out, PCP_KEY_VERSION);
|
buffer_add8(out, PCP_KEY_VERSION);
|
||||||
buffer_add32(out, key->ctime);
|
buffer_add32(out, sk->ctime);
|
||||||
buffer_add8(out, EXP_PK_CIPHER);
|
buffer_add8(out, EXP_PK_CIPHER);
|
||||||
|
|
||||||
/* add the keys */
|
/* add the keys */
|
||||||
buffer_add(raw, key->edpub, 32);
|
buffer_add(raw, sk->masterpub, 32);
|
||||||
buffer_add(raw, key->edpub, 32);
|
buffer_add(raw, sk->edpub, 32);
|
||||||
buffer_add(raw, key->pub, 32);
|
buffer_add(raw, sk->pub, 32);
|
||||||
|
|
||||||
/* add the sig header */
|
/* add the sig header */
|
||||||
buffer_add8(raw, EXP_SIG_VERSION);
|
buffer_add8(raw, EXP_SIG_VERSION);
|
||||||
@@ -57,25 +109,25 @@ Buffer *pcp_get_rfc_pub (pcp_pubkey_t *key, pcp_key_t *sk) {
|
|||||||
/* add key expire time */
|
/* add key expire time */
|
||||||
buffer_add32be(raw, 4);
|
buffer_add32be(raw, 4);
|
||||||
buffer_add8(raw, EXP_SIG_SUB_KEYEXPIRE);
|
buffer_add8(raw, EXP_SIG_SUB_KEYEXPIRE);
|
||||||
buffer_add32be(raw, key->ctime + 31536000);
|
buffer_add32be(raw, sk->ctime + 31536000);
|
||||||
|
|
||||||
/* add name notation sub*/
|
/* add name notation sub*/
|
||||||
size_t notation_size = strlen(key->owner) + 4 + 5;
|
size_t notation_size = strlen(sk->owner) + 4 + 5;
|
||||||
buffer_add32be(raw, notation_size);
|
buffer_add32be(raw, notation_size);
|
||||||
buffer_add8(raw, EXP_SIG_SUB_NOTATION);
|
buffer_add8(raw, EXP_SIG_SUB_NOTATION);
|
||||||
buffer_add16be(raw, 5);
|
buffer_add16be(raw, 5);
|
||||||
buffer_add16be(raw, strlen(key->owner));
|
buffer_add16be(raw, strlen(sk->owner));
|
||||||
buffer_add(raw, "owner", 5);
|
buffer_add(raw, "owner", 5);
|
||||||
buffer_add(raw, key->owner, strlen(key->owner));
|
buffer_add(raw, sk->owner, strlen(sk->owner));
|
||||||
|
|
||||||
/* add mail notation sub */
|
/* add mail notation sub */
|
||||||
notation_size = strlen(key->mail) + 4 + 4;
|
notation_size = strlen(sk->mail) + 4 + 4;
|
||||||
buffer_add32be(raw, notation_size);
|
buffer_add32be(raw, notation_size);
|
||||||
buffer_add8(raw, EXP_SIG_SUB_NOTATION);
|
buffer_add8(raw, EXP_SIG_SUB_NOTATION);
|
||||||
buffer_add16be(raw, 4);
|
buffer_add16be(raw, 4);
|
||||||
buffer_add16be(raw, strlen(key->mail));
|
buffer_add16be(raw, strlen(sk->mail));
|
||||||
buffer_add(raw, "mail", 4);
|
buffer_add(raw, "mail", 4);
|
||||||
buffer_add(raw, key->mail, strlen(key->mail));
|
buffer_add(raw, sk->mail, strlen(sk->mail));
|
||||||
|
|
||||||
/* add key flags */
|
/* add key flags */
|
||||||
buffer_add32be(raw, 1);
|
buffer_add32be(raw, 1);
|
||||||
@@ -91,7 +143,7 @@ Buffer *pcp_get_rfc_pub (pcp_pubkey_t *key, pcp_key_t *sk) {
|
|||||||
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
||||||
|
|
||||||
/* sign the hash */
|
/* sign the hash */
|
||||||
unsigned char *sig = pcp_ed_sign(hash, crypto_generichash_BYTES_MAX, sk->secret);
|
unsigned char *sig = pcp_ed_sign_key(hash, crypto_generichash_BYTES_MAX, sk);
|
||||||
|
|
||||||
/* append the signature packet to the output */
|
/* append the signature packet to the output */
|
||||||
buffer_add(out, buffer_get(raw), buffer_size(raw));
|
buffer_add(out, buffer_get(raw), buffer_size(raw));
|
||||||
|
|||||||
208
src/keymgmt.c
208
src/keymgmt.c
@@ -259,63 +259,118 @@ void pcp_exportsecretkey(pcp_key_t *key, char *outfile) {
|
|||||||
keyid we use the primary key. if no keyid has been given but
|
keyid we use the primary key. if no keyid has been given but
|
||||||
a recipient instead, we try to look up the vault for a match.
|
a recipient instead, we try to look up the vault for a match.
|
||||||
*/
|
*/
|
||||||
void pcp_exportpublic(char *keyid, char *recipient, char *passwd, char *outfile, int pbpcompat) {
|
void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int armor) {
|
||||||
pcp_pubkey_t *key = NULL;
|
|
||||||
|
|
||||||
if(keyid != NULL) {
|
|
||||||
/* look if we've got that one */
|
|
||||||
HASH_FIND_STR(pcppubkey_hash, keyid, key);
|
|
||||||
if(key == NULL) {
|
|
||||||
/* maybe it's a secret key? */
|
|
||||||
pcp_key_t *s = NULL;
|
|
||||||
HASH_FIND_STR(pcpkey_hash, keyid, s);
|
|
||||||
if(s == NULL) {
|
|
||||||
fatal("Could not find a public key with id 0x%s in vault %s!\n", keyid, vault->filename);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
key = pcpkey_pub_from_secret(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* look for the primary secret */
|
|
||||||
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;
|
FILE *out;
|
||||||
|
int is_foreign = 0;
|
||||||
|
pcp_pubkey_t *pk = NULL;
|
||||||
|
pcp_key_t *sk = NULL;
|
||||||
|
Buffer *exported_pk;
|
||||||
|
|
||||||
if(outfile == NULL) {
|
if(outfile == NULL) {
|
||||||
out = stdout;
|
out = stdout;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not create output file %s", outfile);
|
fatal("Could not create output file %s", outfile);
|
||||||
out = NULL;
|
goto errpcpexpu1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(out != NULL) {
|
|
||||||
/* scip */
|
if(keyid != NULL) {
|
||||||
/* printf("EXPORT:\n"); */
|
/* keyid specified, check if it exists and if yes, what type it is */
|
||||||
/* pcpprint_bin(stdout, key, PCP_RAW_PUBKEYSIZE); printf("\n"); */
|
HASH_FIND_STR(pcppubkey_hash, keyid, pk);
|
||||||
pcppubkey_print(key, out, pbpcompat);
|
if(pk == NULL) {
|
||||||
if(pbpcompat)
|
/* ok, so, then look for a secret key with that id */
|
||||||
fprintf(stderr, "public key exported in PBP format.\n");
|
HASH_FIND_STR(pcpkey_hash, keyid, sk);
|
||||||
|
if(sk == NULL) {
|
||||||
|
fatal("Could not find a key with id 0x%s in vault %s!\n",
|
||||||
|
keyid, vault->filename);
|
||||||
|
goto errpcpexpu1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* ok, so it's our own key */
|
||||||
|
is_foreign = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* it's a foreign public key, we cannot sign it ourselfes */
|
||||||
|
is_foreign = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we use our primary key anyway */
|
||||||
|
sk = pcp_find_primary_secret();
|
||||||
|
if(sk == NULL) {
|
||||||
|
fatal("There's no primary secret key in the vault %s!\n", vault->filename);
|
||||||
|
goto errpcpexpu1;
|
||||||
|
}
|
||||||
|
is_foreign = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(is_foreign == 0) {
|
||||||
|
/* decrypt the secret key */
|
||||||
|
char *passphrase;
|
||||||
|
pcp_readpass(&passphrase,
|
||||||
|
"Enter passphrase to decrypt your secret key", NULL, 1);
|
||||||
|
sk = pcpkey_decrypt(sk, passphrase);
|
||||||
|
if(sk == NULL) {
|
||||||
|
goto errpcpexpu1;
|
||||||
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
|
free(passphrase);
|
||||||
|
}
|
||||||
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
|
free(passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now, we're ready for the actual export */
|
||||||
|
if(format == EXP_FORMAT_NATIVE) {
|
||||||
|
if(is_foreign == 0) {
|
||||||
|
exported_pk = pcp_export_rfc_pub(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);
|
||||||
|
FILE *t = fopen("binexp", "wb+");
|
||||||
|
fwrite(buffer_get(exported_pk), 1, buffer_size(exported_pk), t);
|
||||||
|
fclose(t);
|
||||||
|
free(z85);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
fwrite(buffer_get(exported_pk), 1, buffer_size(exported_pk), out);
|
||||||
|
buffer_free(exported_pk);
|
||||||
fprintf(stderr, "public key exported.\n");
|
fprintf(stderr, "public key exported.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
free(key);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* FIXME: export foreign keys unsupported yet */
|
||||||
|
fatal("Exporting foreign public keys in native format unsupported yet");
|
||||||
|
goto errpcpexpu1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(format == EXP_FORMAT_PBP) {
|
||||||
|
if(is_foreign == 0) {
|
||||||
|
exported_pk = pcp_export_pbp_pub(sk);
|
||||||
|
if(exported_pk != NULL) {
|
||||||
|
/* PBP format requires armoring always */
|
||||||
|
size_t zlen;
|
||||||
|
char *z85pbp = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen);
|
||||||
|
fprintf(out, "%s", z85pbp);
|
||||||
|
free(z85pbp);
|
||||||
|
buffer_free(exported_pk);
|
||||||
|
fprintf(stderr, "public key exported in PBP format.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fatal("Exporting foreign public keys in PBP format not possible");
|
||||||
|
goto errpcpexpu1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errpcpexpu1:
|
||||||
|
buffer_free(exported_pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -373,8 +428,9 @@ int pcp_importsecret (vault_t *vault, FILE *in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcp_importpublic (vault_t *vault, FILE *in, int pbpcompat) {
|
int pcp_importpublic (vault_t *vault, FILE *in) {
|
||||||
pcp_pubkey_t *pub = NULL;
|
pcp_pubkey_t *pub = NULL;
|
||||||
|
int pbpcompat = 0;
|
||||||
if(pbpcompat == 1) {
|
if(pbpcompat == 1) {
|
||||||
char *date = NULL;
|
char *date = NULL;
|
||||||
char *parts = NULL;
|
char *parts = NULL;
|
||||||
@@ -626,67 +682,3 @@ char *pcp_find_id_byrec(char *recipient) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -49,18 +49,20 @@ char *pcp_getstdin(const char *prompt);
|
|||||||
int pcp_storekey (pcp_key_t *key);
|
int pcp_storekey (pcp_key_t *key);
|
||||||
void pcp_keygen();
|
void pcp_keygen();
|
||||||
void pcp_listkeys();
|
void pcp_listkeys();
|
||||||
|
|
||||||
void pcp_exportsecret(char *keyid, int useid, char *outfile);
|
void pcp_exportsecret(char *keyid, int useid, char *outfile);
|
||||||
void pcp_exportsecretkey(pcp_key_t *key, char *outfile);
|
void pcp_exportsecretkey(pcp_key_t *key, char *outfile);
|
||||||
|
void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int armor);
|
||||||
|
|
||||||
pcp_key_t *pcp_getrsk(pcp_key_t *s, char *recipient, char *passwd);
|
pcp_key_t *pcp_getrsk(pcp_key_t *s, char *recipient, char *passwd);
|
||||||
void pcp_exportpublic(char *keyid, char *recipient, char *passwd, char *outfile, int pbpcompat);
|
|
||||||
char *pcp_normalize_id(char *keyid);
|
char *pcp_normalize_id(char *keyid);
|
||||||
pcp_key_t *pcp_find_primary_secret();
|
pcp_key_t *pcp_find_primary_secret();
|
||||||
int pcp_importpublic (vault_t *vault, FILE *in, int pbpcompat);
|
|
||||||
|
int pcp_importpublic (vault_t *vault, FILE *in);
|
||||||
int pcp_importsecret (vault_t *vault, FILE *in);
|
int pcp_importsecret (vault_t *vault, FILE *in);
|
||||||
|
|
||||||
void pcpdelete_key(char *keyid);
|
void pcpdelete_key(char *keyid);
|
||||||
char *pcp_find_id_byrec(char *recipient);
|
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 */
|
#endif /* _HAVE_KEYMGMT_H */
|
||||||
|
|||||||
180
src/keyprint.c
180
src/keyprint.c
@@ -85,13 +85,14 @@ int pcptext_infile(char *infile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: can't determine keytype by using its size */
|
||||||
if(clen == PCP_RAW_PUBKEYSIZE) {
|
if(clen == PCP_RAW_PUBKEYSIZE) {
|
||||||
/* public key? */
|
/* public key? */
|
||||||
pcp_pubkey_t *key = (pcp_pubkey_t *)bin;
|
pcp_pubkey_t *key = (pcp_pubkey_t *)bin;
|
||||||
pubkey2native(key);
|
pubkey2native(key);
|
||||||
if(pcp_sanitycheck_pub(key) == 0) {
|
if(pcp_sanitycheck_pub(key) == 0) {
|
||||||
fprintf(stdout, "%s is a public key file:\n", infile);
|
fprintf(stdout, "%s is a public key file:\n", infile);
|
||||||
pcppubkey_print(key, stdout, 0);
|
// pcppubkey_print(key, stdout, 0);
|
||||||
free(key);
|
free(key);
|
||||||
goto tdone;
|
goto tdone;
|
||||||
}
|
}
|
||||||
@@ -127,7 +128,7 @@ void pcptext_key(char *keyid) {
|
|||||||
if(p != NULL) {
|
if(p != NULL) {
|
||||||
if(debug)
|
if(debug)
|
||||||
pcp_dumppubkey(p);
|
pcp_dumppubkey(p);
|
||||||
pcppubkey_print(p, stdout, 0);
|
pcppubkey_print(p, stdout);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("No key with id 0x%s found!\n", keyid);
|
fatal("No key with id 0x%s found!\n", keyid);
|
||||||
@@ -175,141 +176,12 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
|
|||||||
key->owner, key->mail);
|
key->owner, key->mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
|
||||||
void pcpkey_print(pcp_key_t *key, FILE* out) {
|
|
||||||
size_t zlen;
|
size_t zlen;
|
||||||
key2be(key);
|
|
||||||
void *blob = ucmalloc(PCP_RAW_KEYSIZE);
|
|
||||||
pcp_seckeyblob(blob, key);
|
|
||||||
char *z85encoded = pcp_z85_encode((unsigned char*)blob, PCP_RAW_KEYSIZE, &zlen);
|
|
||||||
key2native(key);
|
|
||||||
|
|
||||||
free(blob);
|
|
||||||
|
|
||||||
struct tm *c;
|
struct tm *c;
|
||||||
time_t t = (time_t)key->ctime;
|
time_t t = (time_t)key->ctime;
|
||||||
c = localtime(&t);
|
c = localtime(&t);
|
||||||
|
|
||||||
fprintf(out, "%s\n", PCP_KEY_HEADER);
|
|
||||||
|
|
||||||
fprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
|
||||||
PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
|
||||||
|
|
||||||
fprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE);
|
|
||||||
|
|
||||||
fprintf(out, " Key-ID: 0x%s\n", key->id);
|
|
||||||
|
|
||||||
/* 2004-06-14T23:34:30. */
|
|
||||||
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
|
|
||||||
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
|
|
||||||
c->tm_hour, c->tm_min, c->tm_sec);
|
|
||||||
|
|
||||||
fprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
|
||||||
fprintf(out, " Key Version: 0x%08X\n", key->version);
|
|
||||||
|
|
||||||
fprintf(out, "\n%s\n", z85encoded);
|
|
||||||
|
|
||||||
fprintf(out, "%s\n", PCP_KEY_FOOTER);
|
|
||||||
|
|
||||||
free(z85encoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcppubkey_print(pcp_pubkey_t *key, FILE* out, int pbpcompat) {
|
|
||||||
struct tm *c;
|
|
||||||
time_t t = (time_t)key->ctime;
|
|
||||||
c = localtime(&t);
|
|
||||||
|
|
||||||
if(pbpcompat == 1) {
|
|
||||||
pcp_key_t *secret = NULL;
|
|
||||||
secret = pcp_find_primary_secret();
|
|
||||||
|
|
||||||
if(secret == NULL) {
|
|
||||||
fatal("Could not find a secret key in vault %s!\n", vault->filename);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
char *passphrase;
|
|
||||||
pcp_readpass(&passphrase,
|
|
||||||
"Enter passphrase to decrypt your secret key for signing the export", NULL, 1);
|
|
||||||
|
|
||||||
secret = pcpkey_decrypt(secret, passphrase);
|
|
||||||
if(secret != NULL) {
|
|
||||||
size_t pbplen = crypto_sign_PUBLICKEYBYTES+crypto_box_PUBLICKEYBYTES+crypto_sign_PUBLICKEYBYTES+strlen(key->owner)+64;
|
|
||||||
|
|
||||||
/* we need to do the padding here, since pbp verifies the sig including the pad */
|
|
||||||
/*
|
|
||||||
int pad = pbplen % 4;
|
|
||||||
if(pad > 0) {
|
|
||||||
pad = 4 - pad;
|
|
||||||
pbplen += pad;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned char *blob = ucmalloc(pbplen);
|
|
||||||
|
|
||||||
if(debug) {
|
|
||||||
_dump(" mp", secret->edpub, crypto_sign_PUBLICKEYBYTES);
|
|
||||||
_dump(" cp", key->pub, crypto_sign_PUBLICKEYBYTES);
|
|
||||||
_dump(" sp", key->edpub, crypto_sign_PUBLICKEYBYTES);
|
|
||||||
_dump("name", (unsigned char *)key->owner, strlen(key->owner));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pkt = keys.sign(keys.mp+keys.sp+keys.cp+dates+keys.name, master=True) */
|
|
||||||
memcpy(blob, secret->edpub, crypto_sign_PUBLICKEYBYTES);
|
|
||||||
memcpy(&blob[crypto_sign_PUBLICKEYBYTES], key->edpub, crypto_sign_PUBLICKEYBYTES);
|
|
||||||
memcpy(&blob[crypto_sign_PUBLICKEYBYTES*2], key->pub, crypto_box_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
struct tm *v;
|
|
||||||
time_t vt = t + 31536000;
|
|
||||||
v = localtime(&vt);
|
|
||||||
|
|
||||||
char *date = ucmalloc(65);
|
|
||||||
|
|
||||||
sprintf(date, "%04d-%02d-%02dT%02d:%02d:%02d.000000 %04d-%02d-%02dT%02d:%02d:%02d.000000 ",
|
|
||||||
c->tm_year+1900-1, c->tm_mon+1, c->tm_mday, // wtf? why -1?
|
|
||||||
c->tm_hour, c->tm_min, c->tm_sec,
|
|
||||||
v->tm_year+1900-1, v->tm_mon+1, v->tm_mday,
|
|
||||||
v->tm_hour, v->tm_min, v->tm_sec);
|
|
||||||
|
|
||||||
memcpy(&blob[crypto_sign_PUBLICKEYBYTES+crypto_box_PUBLICKEYBYTES*2], date, 64);
|
|
||||||
|
|
||||||
memcpy(&blob[crypto_sign_PUBLICKEYBYTES+crypto_box_PUBLICKEYBYTES*2+64], key->owner, strlen(key->owner));
|
|
||||||
|
|
||||||
unsigned char *sig = pcp_ed_sign(blob, pbplen, secret);
|
|
||||||
|
|
||||||
if(debug)
|
|
||||||
_dump(" sig", sig, crypto_sign_BYTES+pbplen);
|
|
||||||
|
|
||||||
if(sig != NULL) {
|
|
||||||
size_t siglen = pbplen + crypto_sign_BYTES;
|
|
||||||
size_t blen = ((siglen / 4) * 5) + siglen;
|
|
||||||
char *b85sig = ucmalloc(blen);
|
|
||||||
encode_85(b85sig, sig, siglen);
|
|
||||||
fprintf(out, "%s", b85sig);
|
|
||||||
free(b85sig);
|
|
||||||
free(sig);
|
|
||||||
}
|
|
||||||
free(blob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
size_t zlen;
|
|
||||||
|
|
||||||
/* printf("version: %08x\n", key->version); */
|
|
||||||
|
|
||||||
pubkey2be(key);
|
|
||||||
|
|
||||||
void *blob = ucmalloc(PCP_RAW_PUBKEYSIZE);
|
|
||||||
pcp_pubkeyblob(blob, key);
|
|
||||||
char *z85encoded = pcp_z85_encode((unsigned char*)blob, PCP_RAW_PUBKEYSIZE, &zlen);
|
|
||||||
pubkey2native(key);
|
|
||||||
|
|
||||||
free(blob);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fprintf(out, "%s\n", PCP_PUBKEY_HEADER);
|
|
||||||
|
|
||||||
fprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
fprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
||||||
PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
||||||
|
|
||||||
@@ -351,16 +223,48 @@ void pcppubkey_print(pcp_pubkey_t *key, FILE* out, int pbpcompat) {
|
|||||||
}
|
}
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
|
||||||
fprintf(out, "\n%s\n", z85encoded);
|
|
||||||
|
|
||||||
fprintf(out, "%s\n", PCP_PUBKEY_FOOTER);
|
|
||||||
|
|
||||||
free(hash);
|
free(hash);
|
||||||
free(r);
|
free(r);
|
||||||
free(z85encoded);
|
free(c);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pcpkey_print(pcp_key_t *key, FILE* out) {
|
||||||
|
size_t zlen;
|
||||||
|
key2be(key);
|
||||||
|
void *blob = ucmalloc(PCP_RAW_KEYSIZE);
|
||||||
|
pcp_seckeyblob(blob, key);
|
||||||
|
char *z85encoded = pcp_z85_encode((unsigned char*)blob, PCP_RAW_KEYSIZE, &zlen);
|
||||||
|
key2native(key);
|
||||||
|
|
||||||
|
free(blob);
|
||||||
|
|
||||||
|
struct tm *c;
|
||||||
|
time_t t = (time_t)key->ctime;
|
||||||
|
c = localtime(&t);
|
||||||
|
|
||||||
|
fprintf(out, "%s\n", PCP_KEY_HEADER);
|
||||||
|
|
||||||
|
fprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
||||||
|
PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
||||||
|
|
||||||
|
fprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE);
|
||||||
|
|
||||||
|
fprintf(out, " Key-ID: 0x%s\n", key->id);
|
||||||
|
|
||||||
|
/* 2004-06-14T23:34:30. */
|
||||||
|
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
|
||||||
|
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
|
||||||
|
c->tm_hour, c->tm_min, c->tm_sec);
|
||||||
|
|
||||||
|
fprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
||||||
|
fprintf(out, " Key Version: 0x%08X\n", key->version);
|
||||||
|
|
||||||
|
fprintf(out, "\n%s\n", z85encoded);
|
||||||
|
|
||||||
|
fprintf(out, "%s\n", PCP_KEY_FOOTER);
|
||||||
|
|
||||||
|
free(z85encoded);
|
||||||
|
}
|
||||||
|
|
||||||
void pcp_dumpkey(pcp_key_t *k) {
|
void pcp_dumpkey(pcp_key_t *k) {
|
||||||
int i;
|
int i;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void pcp_dumpkey(pcp_key_t *k);
|
|||||||
void pcp_dumppubkey(pcp_pubkey_t *k);
|
void pcp_dumppubkey(pcp_pubkey_t *k);
|
||||||
|
|
||||||
void pcpkey_print(pcp_key_t *key, FILE *out);
|
void pcpkey_print(pcp_key_t *key, FILE *out);
|
||||||
void pcppubkey_print(pcp_pubkey_t *key, FILE *out, int pbpcompat);
|
void pcppubkey_print(pcp_pubkey_t *key, FILE *out);
|
||||||
|
|
||||||
void pcpkey_printshortinfo(pcp_key_t *key);
|
void pcpkey_printshortinfo(pcp_key_t *key);
|
||||||
void pcppubkey_printshortinfo(pcp_pubkey_t *key);
|
void pcppubkey_printshortinfo(pcp_pubkey_t *key);
|
||||||
|
|||||||
Reference in New Issue
Block a user