mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 12:00:56 +01:00
added own file type for crypt+sign, now signing the encrypted result, not the clear message.
using 64bit integers for time vars in key ex/im_ports
This commit is contained in:
@@ -118,10 +118,12 @@ typedef enum _PCP_KEY_TYPES {
|
|||||||
#ifndef PCP_CBC
|
#ifndef PCP_CBC
|
||||||
#define PCP_ASYM_CIPHER 5
|
#define PCP_ASYM_CIPHER 5
|
||||||
#define PCP_SYM_CIPHER 23
|
#define PCP_SYM_CIPHER 23
|
||||||
|
#define PCP_ASYM_CIPHER_SIG 24
|
||||||
#define PCP_BLOCK_SIZE 32 * 1024
|
#define PCP_BLOCK_SIZE 32 * 1024
|
||||||
#else
|
#else
|
||||||
/* CBC mode, use smaller blocks */
|
/* CBC mode, use smaller blocks */
|
||||||
#define PCP_ASYM_CIPHER 7
|
#define PCP_ASYM_CIPHER 7
|
||||||
|
#define PCP_ASYM_CIPHER_SIG 8
|
||||||
#define PCP_SYM_CIPHER 25
|
#define PCP_SYM_CIPHER 25
|
||||||
#define PCP_BLOCK_SIZE 1 * 1024
|
#define PCP_BLOCK_SIZE 1 * 1024
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,13 +73,19 @@
|
|||||||
those cipher numbers become official, I'll use them instead
|
those cipher numbers become official, I'll use them instead
|
||||||
of my own.
|
of my own.
|
||||||
|
|
||||||
|
- We use 64 bit integers for times everywhere (ctime, expire, etc),
|
||||||
|
to be year 2038 safe. Note, that this is a violation of the
|
||||||
|
RFC spec. However, said RFC have to be modified to fit 2038
|
||||||
|
anc beyond anyways. This applies for the keyfile ctime as
|
||||||
|
well for the key sig sub fields containing time values.
|
||||||
|
|
||||||
- The exported public key packet contains a signature. We're
|
- The exported public key packet contains a signature. We're
|
||||||
filling out all required fields. A signature has a variable
|
filling out all required fields. A signature has a variable
|
||||||
number of sig sub packets. We use only these types:
|
number of sig sub packets. We use only these types:
|
||||||
|
|
||||||
2 = Signature Creation Time (4 byte)
|
2 = Signature Creation Time (8 byte)
|
||||||
3 = Signature Expiration Time (4 byte)
|
3 = Signature Expiration Time (8 byte)
|
||||||
9 = Key Expiration Time (4 bytes)
|
9 = Key Expiration Time (8 bytes)
|
||||||
20 = Notation Data (4 byte flags, N bytes name+value)
|
20 = Notation Data (4 byte flags, N bytes name+value)
|
||||||
27 = Key Flags (1 byte, use 0x02, 0x08 and 0x80
|
27 = Key Flags (1 byte, use 0x02, 0x08 and 0x80
|
||||||
|
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ typedef struct _pcp_stream_t Pcpstream;
|
|||||||
/* various helper structs for mgmt.c, used internally only */
|
/* various helper structs for mgmt.c, used internally only */
|
||||||
struct _pcp_rfc_pubkey_header_t {
|
struct _pcp_rfc_pubkey_header_t {
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
uint32_t ctime;
|
uint64_t ctime;
|
||||||
uint8_t cipher;
|
uint8_t cipher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,14 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t
|
|||||||
else if(head[0] == PCP_ASYM_CIPHER) {
|
else if(head[0] == PCP_ASYM_CIPHER) {
|
||||||
self = 0;
|
self = 0;
|
||||||
}
|
}
|
||||||
|
else if(head[0] == PCP_ASYM_CIPHER_SIG) {
|
||||||
|
self = 0;
|
||||||
|
verify = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fatal(ptx, "Unknown file header (got: %02x)\n", head[0]);
|
||||||
|
goto errdef1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,7 +331,10 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* step 1, file header */
|
/* step 1, file header */
|
||||||
head[0] = PCP_ASYM_CIPHER;
|
if(sign)
|
||||||
|
head[0] = PCP_ASYM_CIPHER_SIG;
|
||||||
|
else
|
||||||
|
head[0] = PCP_ASYM_CIPHER;
|
||||||
ps_write(out, head, 1);
|
ps_write(out, head, 1);
|
||||||
/* fwrite(head, 1, 1, out); */
|
/* fwrite(head, 1, 1, out); */
|
||||||
/* fprintf(stderr, "D: header - 1\n"); */
|
/* fprintf(stderr, "D: header - 1\n"); */
|
||||||
@@ -454,7 +465,8 @@ size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *
|
|||||||
out_size += crypto_secretbox_NONCEBYTES + es;
|
out_size += crypto_secretbox_NONCEBYTES + es;
|
||||||
|
|
||||||
if(recsign != NULL)
|
if(recsign != NULL)
|
||||||
crypto_generichash_update(st, in_buf, cur_bufsize);
|
crypto_generichash_update(st, buf_cipher, es);
|
||||||
|
//crypto_generichash_update(st, in_buf, cur_bufsize);
|
||||||
|
|
||||||
#ifdef PCP_CBC
|
#ifdef PCP_CBC
|
||||||
/* make current cipher to next IV, ignore nonce and pad */
|
/* make current cipher to next IV, ignore nonce and pad */
|
||||||
@@ -573,7 +585,8 @@ size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *
|
|||||||
/* fwrite(buf_clear, ciphersize - PCP_CRYPTO_ADD, 1, out); */
|
/* fwrite(buf_clear, ciphersize - PCP_CRYPTO_ADD, 1, out); */
|
||||||
|
|
||||||
if(recverify != NULL)
|
if(recverify != NULL)
|
||||||
crypto_generichash_update(st, buf_clear, ciphersize - PCP_CRYPTO_ADD);
|
crypto_generichash_update(st, buf_cipher, ciphersize);
|
||||||
|
//crypto_generichash_update(st, buf_clear, ciphersize - PCP_CRYPTO_ADD);
|
||||||
|
|
||||||
free(buf_clear);
|
free(buf_clear);
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,12 @@ int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *su
|
|||||||
ucfree(notation, nsize);
|
ucfree(notation, nsize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* unsupported or ignored sig sub */
|
/* unsupported or ignored sig subs:
|
||||||
|
we (currently) ignore sig ctime, expire and keyexpire,
|
||||||
|
since the ctime - which is the only one we need internally -
|
||||||
|
is already known from the key ctime. This may change in
|
||||||
|
the future though.
|
||||||
|
*/
|
||||||
if(buffer_get_chunk(blob, ignore, subheader->size) == 0) {
|
if(buffer_get_chunk(blob, ignore, subheader->size) == 0) {
|
||||||
fatal(ptx, "Invalid 'unsupported' notation, expected %ld bytes, but got 0\n", subheader->size);
|
fatal(ptx, "Invalid 'unsupported' notation, expected %ld bytes, but got 0\n", subheader->size);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -135,6 +140,7 @@ int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t
|
|||||||
// read hash + sig
|
// read hash + sig
|
||||||
size_t blobstop = blob->offset;
|
size_t blobstop = blob->offset;
|
||||||
size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
|
size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
|
||||||
|
size_t phead = (2 * sizeof(uint8_t)) + sizeof(uint64_t); /* rfc_pub_h */
|
||||||
|
|
||||||
byte *signature = ucmalloc(sigsize);
|
byte *signature = ucmalloc(sigsize);
|
||||||
if(buffer_get_chunk(blob, signature, sigsize) == 0)
|
if(buffer_get_chunk(blob, signature, sigsize) == 0)
|
||||||
@@ -144,11 +150,11 @@ int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t
|
|||||||
sk->type = PCP_KEYSIG_NATIVE;
|
sk->type = PCP_KEYSIG_NATIVE;
|
||||||
|
|
||||||
/* everything minus version, ctime and cipher, 1st 3 fields */
|
/* everything minus version, ctime and cipher, 1st 3 fields */
|
||||||
sk->size = blobstop - 6;
|
sk->size = blobstop - phead;
|
||||||
memcpy(sk->id, p->id, 17);
|
memcpy(sk->id, p->id, 17);
|
||||||
|
|
||||||
/* put the whole signature blob into our keysig */
|
/* put the whole signature blob into our keysig */
|
||||||
blob->offset = 6; /* woah, hack :) */
|
blob->offset = phead;
|
||||||
sk->blob = ucmalloc(sk->size);
|
sk->blob = ucmalloc(sk->size);
|
||||||
buffer_get_chunk(blob, sk->blob, sk->size);
|
buffer_get_chunk(blob, sk->blob, sk->size);
|
||||||
|
|
||||||
@@ -262,7 +268,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) {
|
|||||||
rfc_pub_sig_s *subheader = ucmalloc(sizeof(rfc_pub_sig_s));
|
rfc_pub_sig_s *subheader = ucmalloc(sizeof(rfc_pub_sig_s));
|
||||||
|
|
||||||
if(buffer_done(blob)) goto be;
|
if(buffer_done(blob)) goto be;
|
||||||
p->ctime = buffer_get32na(blob);
|
p->ctime = buffer_get64na(blob);
|
||||||
|
|
||||||
uint8_t pkcipher = buffer_get8(blob);
|
uint8_t pkcipher = buffer_get8(blob);
|
||||||
if(buffer_done(blob)) goto be;
|
if(buffer_done(blob)) goto be;
|
||||||
@@ -352,7 +358,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) {
|
|||||||
date[19] = '\0';
|
date[19] = '\0';
|
||||||
struct tm c;
|
struct tm c;
|
||||||
if(strptime(date, "%Y-%m-%dT%H:%M:%S", &c) == NULL) {
|
if(strptime(date, "%Y-%m-%dT%H:%M:%S", &c) == NULL) {
|
||||||
fatal(ptx, "Failed to parse creation time in PBP public key file (<%s>)\n", date);
|
fatal(ptx, "Failed to parse creation time in PBP public key file\n");
|
||||||
free(date);
|
free(date);
|
||||||
goto errimp2;
|
goto errimp2;
|
||||||
}
|
}
|
||||||
@@ -594,7 +600,7 @@ Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
|
|||||||
|
|
||||||
/* add the header */
|
/* add the header */
|
||||||
buffer_add8(out, PCP_KEY_VERSION);
|
buffer_add8(out, PCP_KEY_VERSION);
|
||||||
buffer_add32be(out, sk->ctime);
|
buffer_add64be(out, sk->ctime);
|
||||||
buffer_add8(out, EXP_PK_CIPHER);
|
buffer_add8(out, EXP_PK_CIPHER);
|
||||||
|
|
||||||
/* add the keys */
|
/* add the keys */
|
||||||
@@ -619,19 +625,19 @@ Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
|
|||||||
buffer_add16be(raw, nsubs);
|
buffer_add16be(raw, nsubs);
|
||||||
|
|
||||||
/* add sig ctime */
|
/* add sig ctime */
|
||||||
buffer_add32be(raw, 4);
|
buffer_add32be(raw, 8);
|
||||||
buffer_add8(raw, EXP_SIG_SUB_CTIME);
|
buffer_add8(raw, EXP_SIG_SUB_CTIME);
|
||||||
buffer_add32be(raw, time(0));
|
buffer_add64be(raw, time(0));
|
||||||
|
|
||||||
/* add sig expire time */
|
/* add sig expire time */
|
||||||
buffer_add32be(raw, 4);
|
buffer_add32be(raw, 8);
|
||||||
buffer_add8(raw, EXP_SIG_SUB_SIGEXPIRE);
|
buffer_add8(raw, EXP_SIG_SUB_SIGEXPIRE);
|
||||||
buffer_add32be(raw, time(0) + 31536000);
|
buffer_add64be(raw, time(0) + 31536000);
|
||||||
|
|
||||||
/* add key expire time */
|
/* add key expire time */
|
||||||
buffer_add32be(raw, 4);
|
buffer_add32be(raw, 8);
|
||||||
buffer_add8(raw, EXP_SIG_SUB_KEYEXPIRE);
|
buffer_add8(raw, EXP_SIG_SUB_KEYEXPIRE);
|
||||||
buffer_add32be(raw, sk->ctime + 31536000);
|
buffer_add64be(raw, sk->ctime + 31536000);
|
||||||
|
|
||||||
size_t notation_size = 0;
|
size_t notation_size = 0;
|
||||||
/* add serial number notation sub */
|
/* add serial number notation sub */
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
|
|||||||
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90);
|
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90);
|
||||||
free(salt);
|
free(salt);
|
||||||
}
|
}
|
||||||
else {
|
else if(head == PCP_ASYM_CIPHER || head == PCP_ASYM_CIPHER_SIG) {
|
||||||
/* asymetric mode */
|
/* asymetric mode */
|
||||||
if(useid) {
|
if(useid) {
|
||||||
secret = pcphash_keyexists(ptx, id);
|
secret = pcphash_keyexists(ptx, id);
|
||||||
@@ -108,11 +108,18 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
|
|||||||
secret = pcpkey_decrypt(ptx, secret, passphrase);
|
secret = pcpkey_decrypt(ptx, secret, passphrase);
|
||||||
if(secret == NULL)
|
if(secret == NULL)
|
||||||
goto errde3;
|
goto errde3;
|
||||||
|
|
||||||
|
if(head == PCP_ASYM_CIPHER_SIG)
|
||||||
|
verify = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
fatal(ptx, "Could not determine input file type (got: %02x)\n", head);
|
||||||
|
goto errde3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal(ptx, "Could not determine input file type\n");
|
fatal(ptx, "Failed to read from file!\n");
|
||||||
goto errde3;
|
goto errde3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user