mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 12:00:56 +01:00
added -L, enhanced -E
This commit is contained in:
@@ -120,7 +120,7 @@ void pcp_listkeys() {
|
|||||||
int nkeys = HASH_COUNT(pcpkey_hash) + HASH_COUNT(pcppubkey_hash);
|
int nkeys = HASH_COUNT(pcpkey_hash) + HASH_COUNT(pcppubkey_hash);
|
||||||
|
|
||||||
if(nkeys > 0) {
|
if(nkeys > 0) {
|
||||||
printf("Key ID Type Creation Time Owner\n");
|
printf("Key ID Type Creation Time Owner\n");
|
||||||
|
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(k) {
|
||||||
pcpkey_printlineinfo(k);
|
pcpkey_printlineinfo(k);
|
||||||
@@ -606,25 +606,70 @@ void pcpedit_key(char *keyid) {
|
|||||||
char *passphrase;
|
char *passphrase;
|
||||||
pcp_readpass(&passphrase, "Enter passphrase to decrypt the key", NULL, 1);
|
pcp_readpass(&passphrase, "Enter passphrase to decrypt the key", NULL, 1);
|
||||||
key = pcpkey_decrypt(key, passphrase);
|
key = pcpkey_decrypt(key, passphrase);
|
||||||
|
ucfree(passphrase, strlen(passphrase));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key != NULL) {
|
if(key != NULL) {
|
||||||
char *owner = pcp_getstdin("Enter the name of the key owner");
|
fprintf(stderr, "Current owner: %s\n", key->owner);
|
||||||
memcpy(key->owner, owner, strlen(owner) + 1);
|
char *owner = pcp_getstdin(" enter new name or press enter to keep current");
|
||||||
|
if(strlen(owner) > 0)
|
||||||
|
memcpy(key->owner, owner, strlen(owner) + 1);
|
||||||
|
|
||||||
char *mail = pcp_getstdin("Enter the email address of the key owner");
|
fprintf(stderr, "Current mail: %s\n", key->mail);
|
||||||
memcpy(key->mail, mail, strlen(mail) + 1);
|
char *mail = pcp_getstdin(" enter new email or press enter to keep current");
|
||||||
|
if(strlen(mail) > 0)
|
||||||
|
memcpy(key->mail, mail, strlen(mail) + 1);
|
||||||
|
|
||||||
|
free(owner);
|
||||||
|
free(mail);
|
||||||
|
|
||||||
|
if(key->type != PCP_KEY_TYPE_MAINSECRET) {
|
||||||
|
pcp_key_t *other = NULL;
|
||||||
|
uint8_t haveprimary = 0;
|
||||||
|
pcphash_iterate(other) {
|
||||||
|
if(other->type == PCP_KEY_TYPE_MAINSECRET) {
|
||||||
|
haveprimary = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *yes = NULL;
|
||||||
|
if(! haveprimary) {
|
||||||
|
fprintf(stderr, "There is currently no primary secret in your vault,\n");
|
||||||
|
yes = pcp_getstdin("want to make this one the primary [yes|NO]?");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "The key %s is currently the primary secret,\n", other->id);
|
||||||
|
yes = pcp_getstdin("want to make this one the primary instead [yes|NO]?");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strncmp(yes, "yes", 1024) == 0) {
|
||||||
|
key->type = PCP_KEY_TYPE_MAINSECRET;
|
||||||
|
if(haveprimary) {
|
||||||
|
fprintf(stderr, "other type: %d\n", other->type);
|
||||||
|
other->type = PCP_KEY_TYPE_SECRET;
|
||||||
|
fprintf(stderr, " new type: %d\n", other->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(yes);
|
||||||
|
}
|
||||||
|
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
pcp_readpass(&passphrase, "Enter passphrase for key encryption", NULL, 1);
|
pcp_readpass(&passphrase,
|
||||||
key = pcpkey_encrypt(key, passphrase);
|
"Enter new passphrase for key encryption (press enter to keep current)",
|
||||||
|
"Enter the passphrase again", 1);
|
||||||
|
|
||||||
|
if(strnlen(passphrase, 1024) > 0) {
|
||||||
|
key = pcpkey_encrypt(key, passphrase);
|
||||||
|
ucfree(passphrase, strlen(passphrase));
|
||||||
|
}
|
||||||
|
|
||||||
if(key != NULL) {
|
if(key != NULL) {
|
||||||
if(debug)
|
if(debug)
|
||||||
pcp_dumpkey(key);
|
pcp_dumpkey(key);
|
||||||
|
|
||||||
vault->unsafed = 1; /* will be safed automatically */
|
vault->unsafed = 1; /* will be safed automatically */
|
||||||
fprintf(stderr, "Key key changed.\n");
|
fprintf(stderr, "Key %s changed.\n", key->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,21 +123,72 @@ void pcpkey_printlineinfo(pcp_key_t *key) {
|
|||||||
c = localtime(&t);
|
c = localtime(&t);
|
||||||
printf("0x%s %s %04d-%02d-%02dT%02d:%02d:%02d %s <%s>\n",
|
printf("0x%s %s %04d-%02d-%02dT%02d:%02d:%02d %s <%s>\n",
|
||||||
key->id,
|
key->id,
|
||||||
(key->type == PCP_KEY_TYPE_MAINSECRET) ? "primary" : " secret",
|
(key->type == PCP_KEY_TYPE_MAINSECRET) ? "primary secret" : "secret ",
|
||||||
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
|
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
|
||||||
c->tm_hour, c->tm_min, c->tm_sec,
|
c->tm_hour, c->tm_min, c->tm_sec,
|
||||||
key->owner, key->mail);
|
key->owner, key->mail);
|
||||||
|
|
||||||
|
if(PCPVERBOSE) {
|
||||||
|
printf(" ");
|
||||||
|
byte *hash = pcpkey_getchecksum(key);
|
||||||
|
int i, y;
|
||||||
|
for(i=0; i<32; i+=4) {
|
||||||
|
for(y=0; y<4; y++) {
|
||||||
|
printf("%02x", hash[i+y]);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
free(hash);
|
||||||
|
printf("\n encrypted: %s, serial: %08x, version: %d\n",
|
||||||
|
(key->secret[0] == '\0') ? "yes" : " no",
|
||||||
|
key->serial, (int)key->version);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
|
void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
|
||||||
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);
|
||||||
printf("0x%s public %04d-%02d-%02dT%02d:%02d:%02d %s <%s>\n",
|
printf("0x%s %s %04d-%02d-%02dT%02d:%02d:%02d %s <%s>\n",
|
||||||
key->id,
|
key->id,
|
||||||
|
(key->valid == 1) ? "valid public " : "public ",
|
||||||
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
|
c->tm_year+1900, c->tm_mon+1, c->tm_mday,
|
||||||
c->tm_hour, c->tm_min, c->tm_sec,
|
c->tm_hour, c->tm_min, c->tm_sec,
|
||||||
key->owner, key->mail);
|
key->owner, key->mail);
|
||||||
|
|
||||||
|
if(PCPVERBOSE) {
|
||||||
|
printf(" ");
|
||||||
|
byte *hash = pcppubkey_getchecksum(key);
|
||||||
|
int i, y;
|
||||||
|
for(i=0; i<32; i+=4) {
|
||||||
|
for(y=0; y<4; y++) {
|
||||||
|
printf("%02x", hash[i+y]);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
free(hash);
|
||||||
|
printf("\n signed: %s, serial: %08x, version: %d, ",
|
||||||
|
(key->valid == 1) ? "yes" : " no",
|
||||||
|
key->serial, (int)key->version);
|
||||||
|
pcp_keysig_t *sig = pcphash_keysigexists(key->id);
|
||||||
|
if(sig != NULL) {
|
||||||
|
printf("signature fingerprint:\n ");
|
||||||
|
byte *checksum = sig->checksum;
|
||||||
|
for(i=0; i<32; i+=4) {
|
||||||
|
for(y=0; y<4; y++) {
|
||||||
|
printf("%02x", checksum[i+y]);
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("fail: no signature stored.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
|
void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
|
||||||
|
|||||||
42
src/pcp.c
42
src/pcp.c
@@ -71,6 +71,8 @@ int main (int argc, char **argv) {
|
|||||||
signcrypt = 0;
|
signcrypt = 0;
|
||||||
exportformat = EXP_FORMAT_NATIVE;
|
exportformat = EXP_FORMAT_NATIVE;
|
||||||
|
|
||||||
|
PCPVERBOSE = 0;
|
||||||
|
|
||||||
static struct option longopts[] = {
|
static struct option longopts[] = {
|
||||||
/* generics */
|
/* generics */
|
||||||
{ "vault", required_argument, NULL, 'V' },
|
{ "vault", required_argument, NULL, 'V' },
|
||||||
@@ -84,27 +86,33 @@ int main (int argc, char **argv) {
|
|||||||
/* key management */
|
/* key management */
|
||||||
{ "keygen", no_argument, NULL, 'k' },
|
{ "keygen", no_argument, NULL, 'k' },
|
||||||
{ "listkeys", no_argument, NULL, 'l' },
|
{ "listkeys", no_argument, NULL, 'l' },
|
||||||
|
{ "listkeys-verbose",no_argument, NULL, 'L' }, /* alias for -l -v */
|
||||||
{ "export-secret", no_argument, NULL, 's' },
|
{ "export-secret", no_argument, NULL, 's' },
|
||||||
{ "export-public", no_argument, NULL, 'p' },
|
{ "export-public", no_argument, NULL, 'p' },
|
||||||
|
{ "export", no_argument, NULL, 'p' }, /* alias -p */
|
||||||
{ "import-secret", no_argument, NULL, 'S' },
|
{ "import-secret", no_argument, NULL, 'S' },
|
||||||
{ "import-public", no_argument, NULL, 'P' },
|
{ "import-public", no_argument, NULL, 'P' },
|
||||||
|
{ "import", no_argument, NULL, 'P' }, /* alias -P */
|
||||||
{ "remove-key", no_argument, NULL, 'R' },
|
{ "remove-key", no_argument, NULL, 'R' },
|
||||||
{ "edit-key", no_argument, NULL, 'E' },
|
{ "edit-key", no_argument, NULL, 'E' },
|
||||||
{ "export-yaml", no_argument, NULL, 'y' },
|
{ "export-yaml", no_argument, NULL, 'y' },
|
||||||
{ "export-format", required_argument, NULL, 'F' },
|
{ "export-format", required_argument, NULL, 'F' },
|
||||||
|
|
||||||
/* crypto */
|
/* crypto */
|
||||||
{ "encrypt", no_argument, NULL, 'e' },
|
{ "encrypt", no_argument, NULL, 'e' },
|
||||||
{ "encrypt-me", no_argument, NULL, 'm' },
|
{ "encrypt-me", no_argument, NULL, 'm' },
|
||||||
{ "decrypt", no_argument, NULL, 'd' },
|
{ "decrypt", no_argument, NULL, 'd' },
|
||||||
|
|
||||||
/* encoding */
|
/* encoding */
|
||||||
{ "z85-encode", no_argument, NULL, 'z' },
|
{ "z85-encode", no_argument, NULL, 'z' },
|
||||||
{ "z85-decode", no_argument, NULL, 'Z' },
|
{ "armor", no_argument, NULL, 'a' }, /* alias -z */
|
||||||
|
{ "textmode", no_argument, NULL, 'a' }, /* alias -z */
|
||||||
|
{ "z85-decode", no_argument, NULL, 'Z' },
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, 'v' },
|
{ "version", no_argument, NULL, '0' }, /* no short opt, FIXME: how to avoid? */
|
||||||
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
{ "debug", no_argument, NULL, 'D' },
|
{ "debug", no_argument, NULL, 'D' },
|
||||||
|
|
||||||
/* signing */
|
/* signing */
|
||||||
@@ -114,7 +122,7 @@ int main (int argc, char **argv) {
|
|||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPRtEx:DzZr:gcymf:b1F:",
|
while ((opt = getopt_long(argc, argv, "klLV:vdehsO:i:I:pSPRtEx:DzaZr:gcymf:b1F:0",
|
||||||
longopts, NULL)) != -1) {
|
longopts, NULL)) != -1) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
@@ -130,6 +138,8 @@ int main (int argc, char **argv) {
|
|||||||
mode += PCP_MODE_KEYGEN;
|
mode += PCP_MODE_KEYGEN;
|
||||||
usevault = 1;
|
usevault = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'L':
|
||||||
|
PCPVERBOSE = 1; /* no break by purpose, turn on -l */
|
||||||
case 'l':
|
case 'l':
|
||||||
mode += PCP_MODE_LISTKEYS;
|
mode += PCP_MODE_LISTKEYS;
|
||||||
usevault = 1;
|
usevault = 1;
|
||||||
@@ -175,6 +185,7 @@ int main (int argc, char **argv) {
|
|||||||
usevault = 1;
|
usevault = 1;
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
|
case 'a':
|
||||||
armor = 1;
|
armor = 1;
|
||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
@@ -229,12 +240,16 @@ int main (int argc, char **argv) {
|
|||||||
strncpy(vaultfile, optarg, 1024);
|
strncpy(vaultfile, optarg, 1024);
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
outfile = ucmalloc(strlen(optarg)+1);
|
if(strncmp(optarg, "-", 2) > 0) {
|
||||||
strncpy(outfile, optarg, strlen(optarg)+1);
|
outfile = ucmalloc(strlen(optarg)+1);
|
||||||
|
strncpy(outfile, optarg, strlen(optarg)+1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
infile = ucmalloc(strlen(optarg)+1);
|
if(strncmp(optarg, "-", 2) > 0) {
|
||||||
strncpy(infile, optarg, strlen(optarg)+1);
|
infile = ucmalloc(strlen(optarg)+1);
|
||||||
|
strncpy(infile, optarg, strlen(optarg)+1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
keyid = ucmalloc(19);
|
keyid = ucmalloc(19);
|
||||||
@@ -255,8 +270,11 @@ int main (int argc, char **argv) {
|
|||||||
case 'D':
|
case 'D':
|
||||||
debug = 1;
|
debug = 1;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case '0':
|
||||||
version();
|
version();
|
||||||
|
case 'v':
|
||||||
|
PCPVERBOSE = 1;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(0);
|
usage(0);
|
||||||
default:
|
default:
|
||||||
|
|||||||
164
tests/decodertest.c
Normal file
164
tests/decodertest.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include <pcp.h>
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
static const char *tell[] = {
|
||||||
|
NULL,
|
||||||
|
"Headers: no, Newlines: yes, Compliant: yes",
|
||||||
|
"Headers: no, Newlines: no, Compliant: yes",
|
||||||
|
"Headers: no, Newlines: yes, Compliant: yes - no begin header",
|
||||||
|
"Headers: yes, Newlines: yes, Compliant: no - empty comment",
|
||||||
|
"Headers: yes, Newlines: yes, Compliant: no - missing z85 char",
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
int ret;
|
||||||
|
size_t clearlen = 256;
|
||||||
|
size_t zlen = (clearlen * 5 / 4);
|
||||||
|
|
||||||
|
if(argc < 2) {
|
||||||
|
fprintf(stderr, "Usage: decodertest <N>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mode;
|
||||||
|
if((mode = strtol(argv[1], NULL, 0)) == 0) {
|
||||||
|
fprintf(stderr, "Error: decoder sub number %s\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *clear = urmalloc(256);
|
||||||
|
char *z85 = ucmalloc(zlen+1);
|
||||||
|
|
||||||
|
/* we encode directly */
|
||||||
|
z85 = zmq_z85_encode(z85, clear, clearlen);
|
||||||
|
|
||||||
|
if(z85 == NULL) {
|
||||||
|
ret = FALSE;
|
||||||
|
if(PCP_ERRSET == 0) {
|
||||||
|
fatal("failed to encoded data to Z85\n");
|
||||||
|
}
|
||||||
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer *Z = buffer_new(384, "z85");
|
||||||
|
buffer_add(Z, z85, zlen);
|
||||||
|
size_t z = buffer_size(Z);
|
||||||
|
size_t i;
|
||||||
|
uint8_t c;
|
||||||
|
|
||||||
|
Pcpstream *out = ps_new_outbuffer();
|
||||||
|
|
||||||
|
/*
|
||||||
|
modi: expect
|
||||||
|
1 = no headers incl newlines ok
|
||||||
|
2 = no headers no newlines ok
|
||||||
|
3 = no begin header ok
|
||||||
|
4 = headers, empty comment fail
|
||||||
|
5 = headers, missing z char fail
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* begin header */
|
||||||
|
if(mode > 3) {
|
||||||
|
ps_print(out, "%s\r\n", PCP_ZFILE_HEADER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* empty comment */
|
||||||
|
if(mode == 4) {
|
||||||
|
ps_print(out, "Version:\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* z85 output */
|
||||||
|
if(mode == 5) {
|
||||||
|
z--;
|
||||||
|
}
|
||||||
|
int l=0;
|
||||||
|
for (i=0; i<z; ++i) {
|
||||||
|
if(mode != 2 && l % 64 == 63 && l > 0) {
|
||||||
|
ps_print(out, "\r\n");
|
||||||
|
l = 0;
|
||||||
|
}
|
||||||
|
c = buffer_get8(Z);
|
||||||
|
ps_write(out, &c, 1);
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* footer */
|
||||||
|
if(mode > 2) {
|
||||||
|
ps_print(out, "\r\n%s\r\n", PCP_ZFILE_FOOTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* done creating z85 file */
|
||||||
|
Buffer *zdone = ps_buffer(out);
|
||||||
|
byte *back = NULL;
|
||||||
|
|
||||||
|
/* control output */
|
||||||
|
|
||||||
|
fprintf(stderr, "%s:\n\n%s\n", tell[mode], buffer_get_str(zdone));
|
||||||
|
|
||||||
|
/* line decoder */
|
||||||
|
|
||||||
|
char *raw = pcp_readz85string(buffer_get(zdone), buffer_size(zdone));
|
||||||
|
|
||||||
|
if(raw == NULL) {
|
||||||
|
/* unexpected */
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
back = pcp_z85_decode(raw, &zlen);
|
||||||
|
if(back == NULL) {
|
||||||
|
if(mode > 3) {
|
||||||
|
/* expected fail */
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* expected ok */
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(mode > 3) {
|
||||||
|
/* expected fail */
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* expected ok */
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finally see if content matches */
|
||||||
|
if(back != NULL) {
|
||||||
|
if(mode <= 3 && memcmp(back, clear, 256) != 0) {
|
||||||
|
ret = FALSE;
|
||||||
|
if(PCP_ERRSET == 0) {
|
||||||
|
fatal("decoded content doesn't match\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finish */
|
||||||
|
ps_close(out);
|
||||||
|
buffer_free(Z);
|
||||||
|
if(raw != NULL)
|
||||||
|
free(raw);
|
||||||
|
if(z85 != NULL)
|
||||||
|
free(z85);
|
||||||
|
|
||||||
|
OUT:
|
||||||
|
if(ret == TRUE) {
|
||||||
|
fprintf(stdout, "%d - ok\n", mode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stdout, "%d - failed\n", mode);
|
||||||
|
fatals_ifany();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user