mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 12:00:56 +01:00
changed z85 header and comment syntax and parser
This commit is contained in:
24
TODO
24
TODO
@@ -17,6 +17,30 @@ vault checksum: add keysigs as well
|
|||||||
|
|
||||||
enable formats for secret key exports as well
|
enable formats for secret key exports as well
|
||||||
|
|
||||||
|
Z85 headers:
|
||||||
|
- currently I use "----- BEGIN ... -----" and "----- END ... -----" as
|
||||||
|
header and footer for various z85 encoded outputs. The problem is, that
|
||||||
|
the "-" character is part of Z85 chars. An input of 0xc6,0x5a,0x0b,0x13 would
|
||||||
|
result z85 encoded as: "-----". So, I cannot be sure, when I find a header
|
||||||
|
delimiter, if it's really a delimiter or legitimate z85 encoded content.
|
||||||
|
Therefore, another delimiter must be used. "~~~~~ BEGIN .... ~~~~~" seems
|
||||||
|
to fit best and "~" is unused in Z85.
|
||||||
|
Then the parser can be enhanced as well. Eg: on startup if a ~ occurs,
|
||||||
|
ignore input until the first non-~ appears. Then decode input until a
|
||||||
|
~ or eof appears, ignore everything after. Comments would still be a
|
||||||
|
problem though. Currently I ignore lines containing whitespaces. But
|
||||||
|
if a file is read blockwise and the blocksize is very small, then a
|
||||||
|
comment line may span multiple blocks and isn't recognizable as a
|
||||||
|
"line" anymore. Maybe, comments shall start and end with a ~ as well, eg:
|
||||||
|
~ BEGIN KEY ~
|
||||||
|
~ Hash: 987298347 ~
|
||||||
|
[z85]
|
||||||
|
~ END KEY ~
|
||||||
|
Here I use the same aproach for the headers, since there would also be
|
||||||
|
the problem how to recognize them properly if a header crosses boundaries
|
||||||
|
or something. By using this scheme, if a ~ is found everything following
|
||||||
|
is marked as to be ignored which could be saved as a state when using
|
||||||
|
blockmode.
|
||||||
|
|
||||||
PCPSTREAM changes:
|
PCPSTREAM changes:
|
||||||
- enable determine armor mode of input, parse headers, comments
|
- enable determine armor mode of input, parse headers, comments
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "helpers++.h"
|
#include "helpers++.h"
|
||||||
|
#include "buffer++.h"
|
||||||
|
|
||||||
namespace pcp {
|
namespace pcp {
|
||||||
|
|
||||||
@@ -57,8 +58,6 @@ namespace pcp {
|
|||||||
|
|
||||||
void is_stored(bool s);
|
void is_stored(bool s);
|
||||||
bool is_stored();
|
bool is_stored();
|
||||||
|
|
||||||
std::string to_text();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator!(PubKey& k);
|
bool operator!(PubKey& k);
|
||||||
@@ -83,7 +82,7 @@ namespace pcp {
|
|||||||
const std::string& mail);
|
const std::string& mail);
|
||||||
Key(pcp_key_t *k);
|
Key(pcp_key_t *k);
|
||||||
Key(pcp_key_t *k, bool store);
|
Key(pcp_key_t *k, bool store);
|
||||||
Key(std::string &z85encoded);
|
Key(std::string &z85encoded, std::string& passphrase);
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
~Key();
|
~Key();
|
||||||
@@ -106,12 +105,14 @@ namespace pcp {
|
|||||||
bool is_encrypted();
|
bool is_encrypted();
|
||||||
bool is_primary();
|
bool is_primary();
|
||||||
|
|
||||||
std::string to_text();
|
std::string export_secret(const std::string& passphrase);
|
||||||
|
std::string export_public();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// << and >> operators
|
// << and >> operators
|
||||||
bool operator!(Key& k);
|
bool operator!(Key& k);
|
||||||
std::ostream& operator<<(std::ostream& output, Key& k);
|
//std::ostream& operator<<(std::ostream& output, Key& k);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,39 +62,23 @@ Key::Key(pcp_key_t *k, bool store) {
|
|||||||
K = k;
|
K = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::Key(string &z85encoded) {
|
Key::Key(string &z85encoded, string &passphrase) {
|
||||||
stored = false;
|
stored = false;
|
||||||
|
|
||||||
if(z85encoded.length() == 0)
|
if(z85encoded.length() == 0)
|
||||||
throw pcp::exception("Error: zero length input");
|
throw pcp::exception("Error: zero length input");
|
||||||
|
|
||||||
size_t clen;
|
pcp_key_t *key = pcp_import_secret((unsigned char *)z85encoded.c_str(), z85encoded.length(), (char *)passphrase.c_str());
|
||||||
unsigned char *z85decoded = pcp_z85_decode((char *)z85encoded.c_str(), &clen);
|
|
||||||
|
|
||||||
if(z85decoded == NULL)
|
if(key == NULL)
|
||||||
throw pcp::exception("Error: could not decode input - it's probably not Z85.\n");
|
throw pcp::exception();
|
||||||
|
|
||||||
if(clen != PCP_RAW_KEYSIZE) {
|
|
||||||
free(z85decoded);
|
|
||||||
char m[256];
|
|
||||||
sprintf(m, "Error: decoded input didn't result to a proper sized key (got %ld bytes)!\n", clen);
|
|
||||||
throw pcp::exception(string(m));
|
|
||||||
}
|
|
||||||
|
|
||||||
// all good now, import the blob
|
|
||||||
pcp_key_t *key = (pcp_key_t *)ucmalloc(sizeof(pcp_key_t));
|
|
||||||
memcpy(key, z85decoded, PCP_RAW_KEYSIZE);
|
|
||||||
key2native(key);
|
|
||||||
|
|
||||||
if(pcp_sanitycheck_key(key) != 0) {
|
if(pcp_sanitycheck_key(key) != 0) {
|
||||||
free(key);
|
free(key);
|
||||||
free(z85decoded);
|
|
||||||
throw pcp::exception();
|
throw pcp::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
K = key;
|
K = key;
|
||||||
cout << 7 << " false" << endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::~Key() {
|
Key::~Key() {
|
||||||
@@ -108,70 +92,42 @@ Key& Key::operator = (const Key &k) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Key::to_text() {
|
string Key::export_secret(const string &passphrase) {
|
||||||
size_t zlen;
|
Buffer *exported_sk;
|
||||||
pcp_key_t *key = K;
|
|
||||||
|
|
||||||
key2be(key);
|
if(passphrase.length() == 0)
|
||||||
void *blob = ucmalloc(PCP_RAW_KEYSIZE);
|
throw pcp::exception("Error: empty passphrase");
|
||||||
pcp_seckeyblob(blob, key);
|
|
||||||
char *z85encoded = pcp_z85_encode((unsigned char*)blob, PCP_RAW_KEYSIZE, &zlen);
|
|
||||||
|
|
||||||
if(PCP_ERRSET == 1)
|
exported_sk = pcp_export_secret(K, (char *)passphrase.c_str());
|
||||||
|
|
||||||
|
if(exported_sk == NULL)
|
||||||
throw pcp::exception();
|
throw pcp::exception();
|
||||||
|
|
||||||
key2native(key);
|
size_t zlen;
|
||||||
|
char *z85 = pcp_z85_encode(buffer_get(exported_sk), buffer_size(exported_sk), &zlen);
|
||||||
|
|
||||||
free(blob);
|
string out = string(EXP_SK_HEADER) + "\r\n" + string(z85) + "\r\n" + string(EXP_SK_FOOTER) + "\r\n";
|
||||||
|
|
||||||
struct tm *c;
|
return out;
|
||||||
time_t t = (time_t)key->ctime;
|
|
||||||
c = localtime(&t);
|
|
||||||
|
|
||||||
string z85;
|
|
||||||
char *out = (char *)ucmalloc(2048);
|
|
||||||
|
|
||||||
sprintf(out, "%s\n", PCP_KEY_HEADER);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
|
||||||
PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " Key-ID: 0x%s\n", key->id);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
//2004-06-14T23:34:30.
|
|
||||||
sprintf(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);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " Key Version: 0x%08X\n", key->version);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, "\n%s\n", z85encoded);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, "%s\n", PCP_KEY_FOOTER);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
free(z85encoded);
|
|
||||||
|
|
||||||
return z85;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& pcp::operator<<(ostream& output, Key& k) {
|
string Key::export_public() {
|
||||||
output << k.to_text();
|
Buffer *exported_pk;
|
||||||
return output;
|
|
||||||
|
exported_pk = pcp_export_rfc_pub(K);
|
||||||
|
|
||||||
|
if(exported_pk == NULL)
|
||||||
|
throw pcp::exception();
|
||||||
|
|
||||||
|
size_t zlen;
|
||||||
|
char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen);
|
||||||
|
|
||||||
|
string out = string(EXP_PK_HEADER) + "\r\n" + string(z85) + "\r\n" + string(EXP_PK_FOOTER) + "\r\n";
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool pcp::operator!(Key& k) {
|
bool pcp::operator!(Key& k) {
|
||||||
if(k.K == NULL)
|
if(k.K == NULL)
|
||||||
return true;
|
return true;
|
||||||
@@ -179,6 +135,7 @@ bool pcp::operator!(Key& k) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Key::encrypt(const string& passphrase) {
|
void Key::encrypt(const string& passphrase) {
|
||||||
K = pcpkey_encrypt(K, (char *)passphrase.c_str());
|
K = pcpkey_encrypt(K, (char *)passphrase.c_str());
|
||||||
if(PCP_ERRSET == 1)
|
if(PCP_ERRSET == 1)
|
||||||
@@ -254,21 +211,18 @@ PubKey::PubKey(pcp_pubkey_t *k, bool store) {
|
|||||||
K = k;
|
K = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME: use Buffer class for stuff like this
|
|
||||||
PubKey::PubKey(string &z85encoded) {
|
PubKey::PubKey(string &z85encoded) {
|
||||||
stored = false;
|
stored = false;
|
||||||
|
|
||||||
if(z85encoded.length() == 0)
|
if(z85encoded.length() == 0)
|
||||||
throw pcp::exception("Error: zero length input");
|
throw pcp::exception("Error: zero length input");
|
||||||
|
|
||||||
Buffer *blob = buffer_new(256, "pub");
|
Buf blob("pub", 256);
|
||||||
buffer_add(blob, z85encoded.c_str(), z85encoded.length());
|
blob.add(z85encoded.c_str(), z85encoded.length());
|
||||||
|
|
||||||
pcp_ks_bundle_t *KS = pcp_import_pub(buffer_get(blob), buffer_size(blob));
|
pcp_ks_bundle_t *KS = pcp_import_pub(buffer_get(blob.get_buffer()), buffer_size(blob.get_buffer()));
|
||||||
|
|
||||||
if(KS == NULL) {
|
if(KS == NULL) {
|
||||||
buffer_free(blob);
|
|
||||||
throw pcp::exception();
|
throw pcp::exception();
|
||||||
}
|
}
|
||||||
pcp_pubkey_t *pub = KS->p;
|
pcp_pubkey_t *pub = KS->p;
|
||||||
@@ -277,7 +231,6 @@ PubKey::PubKey(string &z85encoded) {
|
|||||||
free(KS->p);
|
free(KS->p);
|
||||||
free(KS->s);
|
free(KS->s);
|
||||||
free(KS);
|
free(KS);
|
||||||
buffer_free(blob);
|
|
||||||
throw pcp::exception();
|
throw pcp::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,104 +248,6 @@ PubKey& PubKey::operator = (const PubKey &k) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
string PubKey::to_text() {
|
|
||||||
size_t zlen;
|
|
||||||
pcp_pubkey_t *key = K;
|
|
||||||
|
|
||||||
pubkey2be(key);
|
|
||||||
void *blob = ucmalloc(PCP_RAW_PUBKEYSIZE);
|
|
||||||
pcp_pubkeyblob(blob, key);
|
|
||||||
char *z85encoded = pcp_z85_encode((unsigned char*)blob, PCP_RAW_PUBKEYSIZE, &zlen);
|
|
||||||
|
|
||||||
if(PCP_ERRSET == 1)
|
|
||||||
throw pcp::exception();
|
|
||||||
|
|
||||||
pubkey2native(key);
|
|
||||||
|
|
||||||
free(blob);
|
|
||||||
|
|
||||||
struct tm *c;
|
|
||||||
time_t t = (time_t)key->ctime;
|
|
||||||
c = localtime(&t);
|
|
||||||
|
|
||||||
char *out = (char *)ucmalloc(2048);
|
|
||||||
string z85;
|
|
||||||
|
|
||||||
sprintf(out, "%s\n", PCP_PUBKEY_HEADER);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
|
||||||
PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, " PubKey-ID: 0x%s\n", key->id);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
//2004-06-14T23:34:30.
|
|
||||||
sprintf(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);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
unsigned char *hash = pcppubkey_getchecksum(key);
|
|
||||||
z85 += " Checksum: ";
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for ( i = 0;i <15 ;++i) {
|
|
||||||
sprintf(out, "%02X:",(unsigned int) hash[i]);
|
|
||||||
z85 += out;
|
|
||||||
}
|
|
||||||
sprintf(out, "%02X", hash[15]);
|
|
||||||
z85 += out;
|
|
||||||
z85 += "\n ";
|
|
||||||
|
|
||||||
for ( i = 16;i <31 ;++i) {
|
|
||||||
sprintf(out, "%02X:",(unsigned int) hash[i]);
|
|
||||||
z85 += out;
|
|
||||||
}
|
|
||||||
sprintf(out, "%02X", hash[31]);
|
|
||||||
z85 += out;
|
|
||||||
z85 += "\n";
|
|
||||||
|
|
||||||
sprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
|
||||||
z85 += out;
|
|
||||||
sprintf(out, " Key Version: 0x%08X\n", key->version);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
char *r = pcppubkey_get_art(key);
|
|
||||||
z85 += " Random Art ID: ";
|
|
||||||
int rlen = strlen(r);
|
|
||||||
|
|
||||||
for (i=0; i<rlen; ++i) {
|
|
||||||
if(r[i] == '\n') {
|
|
||||||
z85 += "\n ";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sprintf(out, "%c", r[i]);
|
|
||||||
z85 += out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
z85 += "\n";
|
|
||||||
|
|
||||||
sprintf(out, "\n%s\n", z85encoded);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
sprintf(out, "%s\n", PCP_PUBKEY_FOOTER);
|
|
||||||
z85 += out;
|
|
||||||
|
|
||||||
free(z85encoded);
|
|
||||||
|
|
||||||
return z85;
|
|
||||||
}
|
|
||||||
|
|
||||||
ostream& pcp::operator<<(ostream& output, PubKey& k) {
|
|
||||||
output << k.to_text();
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pcp::operator!(PubKey& k) {
|
bool pcp::operator!(PubKey& k) {
|
||||||
if(k.K == NULL) {
|
if(k.K == NULL) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -58,21 +58,15 @@ typedef unsigned short dbyte; /* Double byte = 16 bits */
|
|||||||
typedef unsigned int qbyte; /* Quad byte = 32 bits */
|
typedef unsigned int qbyte; /* Quad byte = 32 bits */
|
||||||
|
|
||||||
/* key stuff, deprecated. */
|
/* key stuff, deprecated. */
|
||||||
#define PCP_KEY_HEADER "----- BEGIN PCP SECRET KEY -----"
|
#define PCP_ENFILE_HEADER "~~~~~ BEGIN PCP ENCRYPTED FILE ~~~~~"
|
||||||
#define PCP_KEY_FOOTER "------ END PCP SECRET KEY ------"
|
#define PCP_ENFILE_FOOTER "~~~~~ END PCP ENCRYPTED FILE ~~~~~"
|
||||||
|
|
||||||
#define PCP_PUBKEY_HEADER "----- BEGIN PCP PUBLIC KEY -----"
|
#define PCP_ZFILE_HEADER "~~~~~ BEGIN Z85 ENCODED FILE ~~~~~"
|
||||||
#define PCP_PUBKEY_FOOTER "------ END PCP PUBLICKEY ------"
|
#define PCP_ZFILE_FOOTER "~~~~~ END Z85 ENCODED FILE ~~~~~"
|
||||||
|
|
||||||
#define PCP_ENFILE_HEADER "----- BEGIN PCP ENCRYPTED FILE -----"
|
#define PCP_SIG_HEADER "~~~~~ BEGIN ED25519 SIGNED MESSAGE ~~~~~"
|
||||||
#define PCP_ENFILE_FOOTER "------ END PCP ENCRYPTED FILE ------"
|
#define PCP_SIG_START "~~~~~ BEGIN ED25519 SIGNATURE ~~~~~"
|
||||||
|
#define PCP_SIG_END "~~~~~ END ED25519 SIGNATURE ~~~~~"
|
||||||
#define PCP_ZFILE_HEADER "----- BEGIN Z85 ENCODED FILE -----"
|
|
||||||
#define PCP_ZFILE_FOOTER "------ END Z85 ENCODED FILE ------"
|
|
||||||
|
|
||||||
#define PCP_SIG_HEADER "----- BEGIN ED25519 SIGNED MESSAGE -----"
|
|
||||||
#define PCP_SIG_START "----- BEGIN ED25519 SIGNATURE -----"
|
|
||||||
#define PCP_SIG_END "------ END ED25519 SIGNATURE ------"
|
|
||||||
#define PCP_SIGPREFIX "\nnacl-"
|
#define PCP_SIGPREFIX "\nnacl-"
|
||||||
|
|
||||||
#define PCP_ME "Pretty Curved Privacy"
|
#define PCP_ME "Pretty Curved Privacy"
|
||||||
|
|||||||
@@ -109,10 +109,10 @@ typedef struct _pcp_ks_bundle_t pcp_ks_bundle_t;
|
|||||||
#define EXP_SIG_SUB_KEYFLAGS 27
|
#define EXP_SIG_SUB_KEYFLAGS 27
|
||||||
|
|
||||||
/* in armored mode, we're using the usual head+foot */
|
/* in armored mode, we're using the usual head+foot */
|
||||||
#define EXP_PK_HEADER "-----BEGIN ED25519-CURVE29915 PUBLIC KEY-----"
|
#define EXP_PK_HEADER "~~~~~BEGIN ED25519-CURVE29915 PUBLIC KEY~~~~~"
|
||||||
#define EXP_PK_FOOTER "------END ED25519-CURVE29915 PUBLIC KEY------"
|
#define EXP_PK_FOOTER "~~~~~END ED25519-CURVE29915 PUBLIC KEY~~~~~"
|
||||||
#define EXP_SK_HEADER "-----BEGIN ED25519-CURVE29915 PRIVATE KEY-----"
|
#define EXP_SK_HEADER "~~~~~BEGIN ED25519-CURVE29915 PRIVATE KEY~~~~~"
|
||||||
#define EXP_SK_FOOTER "------END ED25519-CURVE29915 PRIVATE KEY------"
|
#define EXP_SK_FOOTER "~~~~~END ED25519-CURVE29915 PRIVATE KEY~~~~~"
|
||||||
|
|
||||||
|
|
||||||
/* pubkey export formats */
|
/* pubkey export formats */
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|||||||
@@ -131,6 +131,17 @@ char *pcp_readz85string(unsigned char *input, size_t bufsize);
|
|||||||
*/
|
*/
|
||||||
size_t _buffer_is_binary(unsigned char *buf, size_t len);
|
size_t _buffer_is_binary(unsigned char *buf, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/** Determine if a char is a Z85 character
|
||||||
|
|
||||||
|
\param[out] z Buffer object where to put the char if it's z85 and not inside a comment.
|
||||||
|
\param[in] c The char to check.
|
||||||
|
\param[in] is_comment Denotes if we're currently within a comment.
|
||||||
|
|
||||||
|
\return Returns 1 if a comment starts or 0 otherwise.
|
||||||
|
*/
|
||||||
|
uint8_t _parse_zchar(Buffer *z, uint8_t c, uint8_t is_comment);
|
||||||
|
|
||||||
#endif /* _HAVE_PCP_Z85_H */
|
#endif /* _HAVE_PCP_Z85_H */
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|||||||
@@ -56,8 +56,9 @@ Pcpstream *ps_new_outbuffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ps_setdetermine(Pcpstream *stream, size_t blocksize) {
|
void ps_setdetermine(Pcpstream *stream, size_t blocksize) {
|
||||||
|
assert(blocksize % 4 == 0);
|
||||||
stream->determine = 1;
|
stream->determine = 1;
|
||||||
stream->blocksize = blocksize;
|
stream->blocksize = blocksize + (5 - (blocksize % 5));
|
||||||
if(stream->cache == NULL) {
|
if(stream->cache == NULL) {
|
||||||
stream->cache = buffer_new(32, "Pcpstreamcache");
|
stream->cache = buffer_new(32, "Pcpstreamcache");
|
||||||
stream->next = buffer_new(32, "Pcpstreamcachenext");
|
stream->next = buffer_new(32, "Pcpstreamcachenext");
|
||||||
@@ -65,6 +66,7 @@ void ps_setdetermine(Pcpstream *stream, size_t blocksize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ps_armor(Pcpstream *stream, size_t blocksize) {
|
void ps_armor(Pcpstream *stream, size_t blocksize) {
|
||||||
|
assert(blocksize % 4 == 0);
|
||||||
stream->armor = 1;
|
stream->armor = 1;
|
||||||
stream->blocksize = blocksize;
|
stream->blocksize = blocksize;
|
||||||
if(stream->cache == NULL) {
|
if(stream->cache == NULL) {
|
||||||
@@ -196,6 +198,53 @@ void ps_determine(Pcpstream *stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t ps_read_decode(Pcpstream *stream, Buffer *cache, void *buf, size_t bufsize) {
|
size_t ps_read_decode(Pcpstream *stream, Buffer *cache, void *buf, size_t bufsize) {
|
||||||
|
size_t zdiff = 1;
|
||||||
|
size_t i = 0;
|
||||||
|
uint8_t is_comment = 0;
|
||||||
|
uint8_t c;
|
||||||
|
Buffer *z = buffer_new(32, "ztemp");
|
||||||
|
byte *_buf = buf;
|
||||||
|
|
||||||
|
if(bufsize > 0) {
|
||||||
|
for(i=0; i<bufsize; ++i) {
|
||||||
|
c = _buf[i];
|
||||||
|
is_comment = _parse_zchar(z, c, is_comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buffer_size(z) < stream->blocksize) {
|
||||||
|
/* blocksize not full, continue with stream source */
|
||||||
|
/* read in bytewise, ignore newlines and add until the block is full */
|
||||||
|
while (buffer_size(z) < stream->blocksize) {
|
||||||
|
if (ps_read_raw(stream, &c, 1) == 1) {
|
||||||
|
is_comment = _parse_zchar(z, c, is_comment);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finally, decode it and put into cache */
|
||||||
|
size_t binlen, outlen;
|
||||||
|
unsigned char *bin = pcp_z85_decode(buffer_get_str(z), &binlen);
|
||||||
|
if(bin == NULL) {
|
||||||
|
/* it's not z85 encoded, so threat it as binary */
|
||||||
|
stream->armor = 1;
|
||||||
|
buffer_add_buf(stream->cache, z);
|
||||||
|
outlen = buffer_size(stream->cache);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* yes, successfully decoded it, put into cache */
|
||||||
|
buffer_add(stream->cache, bin, binlen);
|
||||||
|
outlen = binlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_free(z);
|
||||||
|
|
||||||
|
return outlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ps_read_decodeOLD(Pcpstream *stream, Buffer *cache, void *buf, size_t bufsize) {
|
||||||
size_t zdiff = 1;
|
size_t zdiff = 1;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
Buffer *z = buffer_new(32, "ztemp");
|
Buffer *z = buffer_new(32, "ztemp");
|
||||||
|
|||||||
66
libpcp/z85.c
66
libpcp/z85.c
@@ -37,6 +37,20 @@ size_t _buffer_is_binary(unsigned char *buf, size_t len) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t _parse_zchar(Buffer *z, uint8_t c, uint8_t is_comment) {
|
||||||
|
if(is_comment == 1) {
|
||||||
|
if(c == '~')
|
||||||
|
is_comment = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(c == '~')
|
||||||
|
is_comment = 1;
|
||||||
|
else if(c != '\r' && c != '\n') {
|
||||||
|
buffer_add8(z, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return is_comment;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char *pcp_padfour(unsigned char *src, size_t srclen, size_t *dstlen) {
|
unsigned char *pcp_padfour(unsigned char *src, size_t srclen, size_t *dstlen) {
|
||||||
size_t outlen, zerolen;
|
size_t outlen, zerolen;
|
||||||
@@ -172,54 +186,12 @@ char *pcp_readz85string(unsigned char *input, size_t bufsize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Buffer *z = buffer_new(MAXLINE, "z");
|
Buffer *z = buffer_new(MAXLINE, "z");
|
||||||
Buffer *line = buffer_new(MAXLINE, "line");
|
uint8_t is_comment = 0;
|
||||||
char *oneline;
|
|
||||||
int begin, end;
|
|
||||||
begin = end = 0;
|
|
||||||
char *out = NULL;
|
char *out = NULL;
|
||||||
|
|
||||||
for(i=0; i<bufsize; ++i) {
|
for(i=0; i<bufsize; ++i)
|
||||||
if(input[i] == '\r')
|
is_comment = _parse_zchar(z, input[i], is_comment);
|
||||||
continue;
|
|
||||||
else if(input[i] == '\n') {
|
|
||||||
/* a line is complete */
|
|
||||||
oneline = buffer_get_str(line);
|
|
||||||
if(strncmp(oneline, "-----", 5) == 0 ) {
|
|
||||||
if(begin == 0) {
|
|
||||||
/* a begin header, reset whatever we've got so far in z buffer */
|
|
||||||
begin = 1;
|
|
||||||
buffer_clear(line);
|
|
||||||
buffer_clear(z);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* an end header */
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(strchr(oneline, ' ') != NULL) {
|
|
||||||
/* a comment */
|
|
||||||
buffer_clear(line);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* regular z85 encoded content */
|
|
||||||
buffer_add_buf(z, line);
|
|
||||||
buffer_clear(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* regular line content */
|
|
||||||
buffer_add8(line, input[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(buffer_size(line) > 0 && end != 1) {
|
|
||||||
/* something left in line buffer, probably
|
|
||||||
newline at eof missing or no multiline input */
|
|
||||||
buffer_add_buf(z, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(buffer_size(z) == 0) {
|
if(buffer_size(z) == 0) {
|
||||||
fatal("empty z85 encoded string");
|
fatal("empty z85 encoded string");
|
||||||
@@ -230,13 +202,11 @@ char *pcp_readz85string(unsigned char *input, size_t bufsize) {
|
|||||||
strncpy(out, buffer_get_str(z), buffer_size(z)+1);
|
strncpy(out, buffer_get_str(z), buffer_size(z)+1);
|
||||||
|
|
||||||
buffer_free(z);
|
buffer_free(z);
|
||||||
buffer_free(line);
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
|
||||||
rferr:
|
rferr:
|
||||||
buffer_free(z);
|
buffer_free(z);
|
||||||
buffer_free(line);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,43 +65,7 @@ int pcptext_infile(char *infile) {
|
|||||||
goto errtinf1;
|
goto errtinf1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fprintf(stdout, "have: %d, secret: %d, public: %d, sig: %d, hh: %d\n", (int)clen, */
|
/* FIXME: try to import pk or sk */
|
||||||
/* (int)sizeof(pcp_key_t), (int)sizeof(pcp_pubkey_t), (int)sizeof(pcp_sig_t), (int)sizeof(UT_hash_handle)); */
|
|
||||||
|
|
||||||
if(clen == PCP_RAW_KEYSIZE) {
|
|
||||||
/* secret key? */
|
|
||||||
pcp_key_t *key = (pcp_key_t *)bin;
|
|
||||||
key2native(key);
|
|
||||||
if(pcp_sanitycheck_key(key) == 0) {
|
|
||||||
fprintf(stdout, "%s is a secret key file:\n", infile);
|
|
||||||
pcpkey_print(key, stdout);
|
|
||||||
free(key);
|
|
||||||
goto tdone;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stdout, "%s looks like a secret key but failed sanity checking.\n", infile);
|
|
||||||
free(key);
|
|
||||||
goto errtinf1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: can't determine keytype by using its size */
|
|
||||||
if(clen == PCP_RAW_PUBKEYSIZE) {
|
|
||||||
/* public key? */
|
|
||||||
pcp_pubkey_t *key = (pcp_pubkey_t *)bin;
|
|
||||||
pubkey2native(key);
|
|
||||||
if(pcp_sanitycheck_pub(key) == 0) {
|
|
||||||
fprintf(stdout, "%s is a public key file:\n", infile);
|
|
||||||
// pcppubkey_print(key, stdout, 0);
|
|
||||||
free(key);
|
|
||||||
goto tdone;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stdout, "%s looks like a publickey but failed sanity checking.\n", infile);
|
|
||||||
free(key);
|
|
||||||
goto errtinf1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* still there? */
|
/* still there? */
|
||||||
fprintf(stdout, "%s looks Z85 encoded but otherwise unknown and is possibly encrypted.\n", infile);
|
fprintf(stdout, "%s looks Z85 encoded but otherwise unknown and is possibly encrypted.\n", infile);
|
||||||
@@ -182,16 +146,13 @@ void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
|
|||||||
time_t t = (time_t)key->ctime;
|
time_t t = (time_t)key->ctime;
|
||||||
c = localtime(&t);
|
c = localtime(&t);
|
||||||
|
|
||||||
fprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
fprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE);
|
||||||
PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
|
||||||
|
|
||||||
fprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE);
|
fprintf(out, " Owner: %s\n", key->owner);
|
||||||
|
fprintf(out, " Mail: %s\n", key->mail);
|
||||||
|
|
||||||
fprintf(out, " Owner: %s\n", key->owner);
|
fprintf(out, " Key-ID: 0x%s\n", key->id);
|
||||||
fprintf(out, " Mail: %s\n", key->mail);
|
fprintf(out, " Public-Key: %s\n", pcp_z85_encode(key->pub, 32, &zlen));
|
||||||
|
|
||||||
fprintf(out, " Key-ID: 0x%s\n", key->id);
|
|
||||||
fprintf(out, " Public-Key: %s\n", pcp_z85_encode(key->pub, 32, &zlen));
|
|
||||||
|
|
||||||
/* 2004-06-14T23:34:30. */
|
/* 2004-06-14T23:34:30. */
|
||||||
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
|
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
|
||||||
@@ -199,23 +160,23 @@ void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
|
|||||||
c->tm_hour, c->tm_min, c->tm_sec);
|
c->tm_hour, c->tm_min, c->tm_sec);
|
||||||
|
|
||||||
unsigned char *hash = pcppubkey_getchecksum(key);
|
unsigned char *hash = pcppubkey_getchecksum(key);
|
||||||
fprintf(out, " Checksum: ");
|
fprintf(out, " Checksum: ");
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for ( i = 0;i <15 ;++i) fprintf(out, "%02X:",(unsigned int) hash[i]);
|
for ( i = 0;i <15 ;++i) fprintf(out, "%02X:",(unsigned int) hash[i]);
|
||||||
fprintf(out, "%02X", hash[15]);
|
fprintf(out, "%02X", hash[15]);
|
||||||
fprintf(out, "\n ");
|
fprintf(out, "\n ");
|
||||||
for ( i = 16;i <31 ;++i) fprintf(out, "%02X:",(unsigned int) hash[i]);
|
for ( i = 16;i <31 ;++i) fprintf(out, "%02X:",(unsigned int) hash[i]);
|
||||||
fprintf(out, "%02X", hash[31]);
|
fprintf(out, "%02X", hash[31]);
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
fprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
fprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
||||||
fprintf(out, " Key Version: 0x%08X\n", key->version);
|
fprintf(out, " Key Version: 0x%08X\n", key->version);
|
||||||
|
|
||||||
char *r = pcppubkey_get_art(key);
|
char *r = pcppubkey_get_art(key);
|
||||||
fprintf(out, " Random Art ID: ");
|
fprintf(out, " Random Art ID: ");
|
||||||
for (i=0; i<strlen(r); ++i) {
|
for (i=0; i<strlen(r); ++i) {
|
||||||
if(r[i] == '\n') {
|
if(r[i] == '\n') {
|
||||||
fprintf(out, "\n ");
|
fprintf(out, "\n ");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(out, "%c", r[i]);
|
fprintf(out, "%c", r[i]);
|
||||||
@@ -228,44 +189,24 @@ void pcppubkey_print(pcp_pubkey_t *key, FILE* out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pcpkey_print(pcp_key_t *key, FILE* out) {
|
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;
|
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, " Cipher: %s\n", PCP_KEY_PRIMITIVE);
|
||||||
|
|
||||||
fprintf(out, " Generated by: %s Version %d.%d.%d\n",
|
fprintf(out, " Key-ID: 0x%s\n", key->id);
|
||||||
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. */
|
/* 2004-06-14T23:34:30. */
|
||||||
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
|
fprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n",
|
||||||
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);
|
||||||
|
|
||||||
fprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
fprintf(out, " Serial Number: 0x%08X\n", key->serial);
|
||||||
fprintf(out, " Key Version: 0x%08X\n", key->version);
|
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 pcpkey_printshortinfo(pcp_key_t *key) {
|
void pcpkey_printshortinfo(pcp_key_t *key) {
|
||||||
int i;
|
int i;
|
||||||
printf(" Key-ID: 0x%s\n", key->id);
|
printf(" Key-ID: 0x%s\n", key->id);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ int main() {
|
|||||||
|
|
||||||
/* out output stream, z85 encoded, use z85 blocksize 8 */
|
/* out output stream, z85 encoded, use z85 blocksize 8 */
|
||||||
Pcpstream *pout = ps_new_file(out);
|
Pcpstream *pout = ps_new_file(out);
|
||||||
|
ps_print(pout, "~~~~~ BEGIN ~~~~~\r\n");
|
||||||
ps_armor(pout, 8);
|
ps_armor(pout, 8);
|
||||||
|
|
||||||
/* "encrypt" a couple of times into the output stream */
|
/* "encrypt" a couple of times into the output stream */
|
||||||
@@ -31,6 +32,8 @@ int main() {
|
|||||||
|
|
||||||
/* done, put cached buffers out and close */
|
/* done, put cached buffers out and close */
|
||||||
ps_finish(pout);
|
ps_finish(pout);
|
||||||
|
pout->armor = 0;
|
||||||
|
ps_print(pout, "\r\n~~~~~ END ~~~~~\r\n");
|
||||||
ps_close(pout);
|
ps_close(pout);
|
||||||
fclose(out);
|
fclose(out);
|
||||||
|
|
||||||
@@ -41,10 +44,8 @@ int main() {
|
|||||||
}
|
}
|
||||||
Pcpstream *pin = ps_new_file(in);
|
Pcpstream *pin = ps_new_file(in);
|
||||||
|
|
||||||
/* enable autmatically encoding detection.
|
/* enable autmatically encoding detection. */
|
||||||
set blocksize to 10, because:
|
ps_setdetermine(pin, 8);
|
||||||
8 + (5 - (8 % 5)) == 10 */
|
|
||||||
ps_setdetermine(pin, 10);
|
|
||||||
|
|
||||||
/* we'll use this stream to put the "decrypted" data in.
|
/* we'll use this stream to put the "decrypted" data in.
|
||||||
note, that this could be a file as well. */
|
note, that this could be a file as well. */
|
||||||
|
|||||||
Reference in New Issue
Block a user