Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/lavabit/magma.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLadar Levison <ladar@lavabit.com>2017-06-20 07:46:14 +0300
committerLadar Levison <ladar@lavabit.com>2017-06-20 07:46:14 +0300
commitec00019570d224896e4dc7f181b8b43fb42e6dce (patch)
tree9eee9d3c66b0e655d7b7a289e38886e1da8d44a0
parent3b82a57bcb1b32751b256d63c8aef3c7c5963cc3 (diff)
parentd19064af6b8f44a16fbf79e5ca8dff8fbe895897 (diff)
Merge remote-tracking branch 'jpadkins/feature/spanning-chunks' into fix/networking-code-cleanup
-rw-r--r--check/magma/prime/prime_check.c96
-rw-r--r--src/core/strings/length.c2
-rw-r--r--src/providers/prime/messages/chunks/chunks.h4
-rw-r--r--src/providers/prime/messages/chunks/encrypted.c25
-rw-r--r--src/providers/prime/messages/messages.c131
-rw-r--r--src/providers/prime/prime.h4
-rw-r--r--src/servers/imap/fetch.c4
7 files changed, 225 insertions, 41 deletions
diff --git a/check/magma/prime/prime_check.c b/check/magma/prime/prime_check.c
index 85d3c8c4..2c03bf98 100644
--- a/check/magma/prime/prime_check.c
+++ b/check/magma/prime/prime_check.c
@@ -123,8 +123,8 @@ START_TEST (check_prime_chunk_ephemeral_s) {
bool_t result = true;
ed25519_key_t *signing = NULL;
secp256k1_key_t *encryption = NULL;
- prime_ephemeral_chunk_t *get = NULL, *set = NULL;
stringer_t *errmsg = MANAGEDBUF(1024);
+ prime_ephemeral_chunk_t *get = NULL, *set = NULL;
if (status()) {
@@ -180,9 +180,9 @@ START_TEST (check_prime_chunk_encrypted_s) {
bool_t result = true;
prime_encrypted_chunk_t *chunk = NULL;
prime_chunk_keys_t encrypt_keys, decrypt_keys;
+ ed25519_key_t *signing_pub = NULL, *signing_priv = NULL;
prime_chunk_keks_t *encrypt_keks = NULL, *decrypt_keks = NULL;
stringer_t *errmsg = MANAGEDBUF(1024), *data = NULL, *set = NULL;
- ed25519_key_t *signing_pub = NULL, *signing_priv = NULL;
secp256k1_key_t *encryption_pub = NULL, *encryption_priv = NULL, *recipient_pub = NULL, *recipient_priv = NULL;
if (status()) {
@@ -217,11 +217,11 @@ START_TEST (check_prime_chunk_encrypted_s) {
}
// Test chunk creation using an ephemeral signing/encryption key, and a recipient public key.
- else if (result && !(chunk = encrypted_chunk_get(PRIME_CHUNK_COMMON, signing_priv, encrypt_keks, data))) {
+ else if (result && !(chunk = encrypted_chunk_set(PRIME_CHUNK_COMMON, signing_priv, encrypt_keks, data, 0))) {
st_sprint(errmsg, "Encrypted chunk creation failed.");
result = false;
}
- else if (result && !(set = encrypted_chunk_set(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) {
+ else if (result && !(set = encrypted_chunk_get(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) {
st_sprint(errmsg, "Encrypted chunk parsing failed.");
result = false;
}
@@ -238,11 +238,11 @@ START_TEST (check_prime_chunk_encrypted_s) {
data = rand_choices("0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " \
"+!@#$%^&*()_|\"?><{}>~`<[]/.,;'\\-=\n\t", 1024, MANAGEDBUF(1024));
- if (result && !(chunk = encrypted_chunk_get(PRIME_CHUNK_HEADERS, signing_priv, encrypt_keks, data))) {
+ if (result && !(chunk = encrypted_chunk_set(PRIME_CHUNK_HEADERS, signing_priv, encrypt_keks, data, 0))) {
st_sprint(errmsg, "Encrypted chunk creation failed.");
result = false;
}
- else if (result && !(set = encrypted_chunk_set(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) {
+ else if (result && !(set = encrypted_chunk_get(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) {
st_sprint(errmsg, "Encrypted chunk parsing failed.");
result = false;
}
@@ -260,11 +260,11 @@ START_TEST (check_prime_chunk_encrypted_s) {
data = rand_choices("0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " \
"+!@#$%^&*()_|\"?><{}>~`<[]/.,;'\\-=\n\t", 1024, MANAGEDBUF(1024));
- if (result && !(chunk = encrypted_chunk_get(PRIME_CHUNK_BODY, signing_priv, encrypt_keks, data))) {
+ if (result && !(chunk = encrypted_chunk_set(PRIME_CHUNK_BODY, signing_priv, encrypt_keks, data, 0))) {
st_sprint(errmsg, "Encrypted chunk creation failed.");
result = false;
}
- else if (result && !(set = encrypted_chunk_set(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) {
+ else if (result && !(set = encrypted_chunk_get(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) {
st_sprint(errmsg, "Encrypted chunk parsing failed.");
result = false;
}
@@ -296,16 +296,16 @@ END_TEST
START_TEST (check_prime_chunk_signature_s) {
log_disable();
- bool_t result = true;
size_t length = 0;
- prime_chunk_keys_t encrypt_keys, decrypt_keys;
- prime_ephemeral_chunk_t *ephemeral = NULL;
+ bool_t result = true;
prime_signature_tree_t *tree = NULL;
+ prime_ephemeral_chunk_t *ephemeral = NULL;
+ prime_chunk_keys_t encrypt_keys, decrypt_keys;
ed25519_key_t *signing_pub = NULL, *signing_priv = NULL;
prime_chunk_keks_t *encrypt_keks = NULL, *decrypt_keks = NULL;
prime_encrypted_chunk_t *common = NULL, *headers = NULL, *body = NULL;
- stringer_t *errmsg = MANAGEDBUF(1024), *payload = MANAGEDBUF(1024), *treesig = NULL, *data = NULL, *full = NULL;
secp256k1_key_t *encryption_pub = NULL, *encryption_priv = NULL, *recipient_pub = NULL, *recipient_priv = NULL;
+ stringer_t *errmsg = MANAGEDBUF(1024), *payload = MANAGEDBUF(1024), *treesig = NULL, *data = NULL, *full = NULL;
if (status()) {
@@ -344,19 +344,19 @@ START_TEST (check_prime_chunk_signature_s) {
result = false;
}
- common = encrypted_chunk_get(PRIME_CHUNK_COMMON, signing_priv, encrypt_keks, payload);
+ common = encrypted_chunk_set(PRIME_CHUNK_COMMON, signing_priv, encrypt_keks, payload, 0);
if (signature_tree_add(tree, encrypted_chunk_buffer(common))) {
st_sprint(errmsg, "Tree signature creation failed.");
result = false;
}
- headers = encrypted_chunk_get(PRIME_CHUNK_HEADERS, signing_priv, encrypt_keks, payload);
+ headers = encrypted_chunk_set(PRIME_CHUNK_HEADERS, signing_priv, encrypt_keks, payload, 0);
if (signature_tree_add(tree, encrypted_chunk_buffer(headers))) {
st_sprint(errmsg, "Tree signature creation failed.");
result = false;
}
- body = encrypted_chunk_get(PRIME_CHUNK_BODY, signing_priv, encrypt_keks, payload);
+ body = encrypted_chunk_set(PRIME_CHUNK_BODY, signing_priv, encrypt_keks, payload, 0);
if (signature_tree_add(tree, encrypted_chunk_buffer(body))) {
st_sprint(errmsg, "Tree signature creation failed.");
result = false;
@@ -406,9 +406,71 @@ START_TEST (check_prime_chunk_signature_s) {
}
END_TEST
+START_TEST (check_prime_chunk_compressed_s) {
+
+ log_disable();
+ bool_t outcome = false;
+ stringer_t *errmsg = MANAGEDBUF(1024);
+
+ log_test("PRIME / CHUNKS / COMPRESSED / SINGLE THREADED:", NULLER("SKIPPED"));
+ ck_assert_msg(outcome, st_char_get(errmsg));
+}
+END_TEST
+
+START_TEST (check_prime_chunk_spanning_s) {
+
+ //log_disable();
+ log_enable();
+ bool_t outcome = true;
+ stringer_t *raw = NULL, *message = NULL, *rebuilt = NULL, *errmsg = MANAGEDBUF(1024);
+ prime_t *destination = NULL, *org = NULL, *recipient = NULL, *request = NULL, *signet = NULL;
+
+ if (status()) {
+
+ if (!(destination = prime_key_generate(PRIME_ORG_KEY, NONE)) || !(org = prime_signet_generate(destination)) ||
+ !(recipient = prime_key_generate(PRIME_USER_KEY, NONE)) || !(request = prime_request_generate(recipient, NULL)) ||
+ !(signet = prime_request_sign(request, destination))) {
+ st_sprint(errmsg, "PRIME message test identity generation failed.");
+ outcome = false;
+ }
+ // Generate a large (> 16mb) random buffer for the message body.
+ else if (!(raw = rand_choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 20971520, NULL))) {
+ st_sprint(errmsg, "Unable to generate random message.");
+ outcome = false;
+ }
+ else if (!(message = prime_message_encrypt(raw, NULL, NULL, destination, signet))) {
+ st_sprint(errmsg, "PRIME message encryption test failed.");
+ outcome = false;
+ }
+ else if (!(rebuilt = prime_message_decrypt(message, org, recipient))) {
+ st_sprint(errmsg, "PRIME message decryption test failed.");
+ outcome = false;
+ }
+ else if (st_cmp_cs_eq(raw, rebuilt)) {
+ st_sprint(errmsg, "PRIME message encryption before and after comparison test failed.");
+ outcome = false;
+ }
+
+ st_cleanup(message, rebuilt, raw);
+ raw = rebuilt = message;
+
+ prime_cleanup(destination);
+ prime_cleanup(recipient);
+ prime_cleanup(request);
+ prime_cleanup(signet);
+ prime_cleanup(org);
+
+ }
+
+ log_test("PRIME / CHUNKS / SPANNING / SINGLE THREADED:", errmsg);
+ ck_assert_msg(outcome, st_char_get(errmsg));
+}
+END_TEST
+
START_TEST (check_prime_message_naked_s) {
-// log_disable();
+ //log_disable();
+ log_enable();
bool_t result = true;
uint32_t max = check_message_max();
stringer_t *raw = NULL, *message = NULL, *rebuilt = NULL, *errmsg = MANAGEDBUF(1024);
@@ -490,6 +552,8 @@ Suite * suite_check_prime(void) {
suite_check_testcase(s, "PRIME", "PRIME Ephemeral Chunks/S", check_prime_chunk_ephemeral_s);
suite_check_testcase(s, "PRIME", "PRIME Encrypted Chunks/S", check_prime_chunk_encrypted_s);
suite_check_testcase(s, "PRIME", "PRIME Signature Chunks/S", check_prime_chunk_signature_s);
+ suite_check_testcase(s, "PRIME", "PRIME Compressed Chunks/S", check_prime_chunk_compressed_s);
+ suite_check_testcase(s, "PRIME", "PRIME Spanning Chunks/S", check_prime_chunk_spanning_s);
suite_check_testcase(s, "PRIME", "PRIME Naked Messages/S", check_prime_message_naked_s);
suite_check_testcase(s, "PRIME", "PRIME Native Messages/S", check_prime_message_native_s);
diff --git a/src/core/strings/length.c b/src/core/strings/length.c
index 9d98ae89..81c76361 100644
--- a/src/core/strings/length.c
+++ b/src/core/strings/length.c
@@ -15,8 +15,8 @@
size_t st_length_get(stringer_t *s) {
char *data;
+ uint32_t opts;
size_t result = 0;
- uint32_t opts; ;
if (!s || !(opts = *((uint32_t *)s))) {
return 0;
diff --git a/src/providers/prime/messages/chunks/chunks.h b/src/providers/prime/messages/chunks/chunks.h
index 19c77197..6d9f914b 100644
--- a/src/providers/prime/messages/chunks/chunks.h
+++ b/src/providers/prime/messages/chunks/chunks.h
@@ -55,8 +55,8 @@ prime_encrypted_chunk_t * encrypted_chunk_alloc(void);
stringer_t * encrypted_chunk_buffer(prime_encrypted_chunk_t *chunk);
void encrypted_chunk_cleanup(prime_encrypted_chunk_t *chunk);
void encrypted_chunk_free(prime_encrypted_chunk_t *chunk);
-prime_encrypted_chunk_t * encrypted_chunk_get(prime_message_chunk_type_t type, ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *data);
-stringer_t * encrypted_chunk_set(ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *chunk, stringer_t *output);
+prime_encrypted_chunk_t * encrypted_chunk_set(prime_message_chunk_type_t type, ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *data, uint8_t flags);
+stringer_t * encrypted_chunk_get(ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *chunk, stringer_t *output);
#endif
diff --git a/src/providers/prime/messages/chunks/encrypted.c b/src/providers/prime/messages/chunks/encrypted.c
index 59d4cd35..5d5a300f 100644
--- a/src/providers/prime/messages/chunks/encrypted.c
+++ b/src/providers/prime/messages/chunks/encrypted.c
@@ -1,4 +1,3 @@
-
/**
* @file /magma/providers/prime/messages/chunks/encrypted.c
*
@@ -11,12 +10,12 @@ void encrypted_chunk_free(prime_encrypted_chunk_t *chunk) {
if (chunk) {
- if (chunk->signature) st_free(chunk->signature);
if (chunk->data) st_free(chunk->data);
+ if (chunk->slots) slots_free(chunk->slots);
if (chunk->trailing) st_free(chunk->trailing);
if (chunk->encrypted) st_free(chunk->encrypted);
-
- if (chunk->slots) slots_free(chunk->slots);
+ if (chunk->signature) st_free(chunk->signature);
+ if (chunk->next) encrypted_chunk_free(chunk->next);
mm_free(chunk);
}
@@ -59,6 +58,13 @@ stringer_t * encrypted_chunk_buffer(prime_encrypted_chunk_t *chunk) {
buffer = chunk->encrypted;
}
+ // If the *next pointer is set then this is part of a series of
+ // spanning chunks.
+ while (chunk->next) {
+ buffer = st_append(buffer, chunk->next);
+ chunk = chunk->next;
+ }
+
return buffer;
}
@@ -66,7 +72,7 @@ stringer_t * encrypted_chunk_buffer(prime_encrypted_chunk_t *chunk) {
* @brief Generate an encrypted message chunk. The signing and encryption keys are required, along with the public encryption
* key for at least one actor.
*/
-prime_encrypted_chunk_t * encrypted_chunk_get(prime_message_chunk_type_t type, ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *data) {
+prime_encrypted_chunk_t * encrypted_chunk_set(prime_message_chunk_type_t type, ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *data, uint8_t flags) {
uint32_t big_endian_length = 0;
prime_chunk_slots_t *slots = NULL;
@@ -102,7 +108,7 @@ prime_encrypted_chunk_t * encrypted_chunk_get(prime_message_chunk_type_t type, e
result->pad += (256 - (result->pad + result->length + 69));
}
- result->flags = 0;
+ result->flags = flags;
big_endian_length = htobe32(result->length);
// Allocate a buffer for the serialized payload, and a buffer to store the padding bytes, then initialize the padding
@@ -162,7 +168,8 @@ prime_encrypted_chunk_t * encrypted_chunk_get(prime_message_chunk_type_t type, e
return result;
}
-stringer_t * encrypted_chunk_set(ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *chunk, stringer_t *output) {
+// Decrypt
+stringer_t * encrypted_chunk_get(ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *chunk, stringer_t *output) {
int32_t payload_size = 0;
uint32_t big_endian_size = 0;
@@ -209,14 +216,12 @@ stringer_t * encrypted_chunk_set(ed25519_key_t *signing, prime_chunk_keks_t *kek
st_length_get(chunk), (payload_size + slot_size + 4));
return NULL;
}
-
// Key slots.
else if (!(key = slots_get(type, PLACER(st_data_get(chunk) + payload_size + 4, slot_size), keks, MANAGEDBUF(32))) ||
!(stretched = hash_sha512(key, MANAGEDBUF(64)))) {
log_pedantic("Key slot parsing failed.s");
return NULL;
}
-
// Decrypt.
else if (!(payload = aes_chunk_decrypt(stretched, PLACER(st_data_get(chunk), st_length_get(chunk) - slot_size), NULL))) {
log_pedantic("Chunk decryption failed.");
@@ -228,7 +233,6 @@ stringer_t * encrypted_chunk_set(ed25519_key_t *signing, prime_chunk_keks_t *kek
st_free(payload);
return NULL;
}
-
// Verify the signature.
else if (ed25519_verify(signing, PLACER(st_data_get(payload) + ED25519_SIGNATURE_LEN, st_length_get(payload) - ED25519_SIGNATURE_LEN),
PLACER(st_data_get(payload), ED25519_SIGNATURE_LEN))) {
@@ -280,4 +284,3 @@ stringer_t * encrypted_chunk_set(ed25519_key_t *signing, prime_chunk_keks_t *kek
st_free(payload);
return result;
}
-
diff --git a/src/providers/prime/messages/messages.c b/src/providers/prime/messages/messages.c
index 3bc72653..10441e03 100644
--- a/src/providers/prime/messages/messages.c
+++ b/src/providers/prime/messages/messages.c
@@ -69,10 +69,116 @@ prime_message_t * encrypted_message_alloc(void) {
return result;
}
+/* @brief Get the part as an encrypted data buffer.
+ *
+ * @param payload
+ * @param type
+ * @param keks
+ * @param signing
+ *
+ * @return
+ */
+prime_encrypted_chunk_t * part_encrypt(stringer_t *payload, uint8_t type, prime_chunk_keks_t *keks, ed25519_key_t *signing) {
+
+ size_t num_chunks = 0;
+ stringer_t *slice = NULL;
+ prime_encrypted_chunk_t *chunk = NULL, *prev = NULL, *curr = NULL;
+
+ if (!(slice = PLACER(st_data_get(payload), st_length_get(payload))) ||
+ !(num_chunks = (st_length_get(payload) / 16777098) + 1)) {
+ return NULL;
+ }
+
+ // Create a stringer with a serialized set of encrypted chunks. If necessary the payload is split into multiple chunks.
+ // Pass this into encrypted_chunk_get() each portion of the payload. Note you'll need to tell the set that it's a span,
+ // or have the chunk get do the splitting.Return the serialized encrypted_chunk_get() values buffer, combining as necessary.
+
+ for (size_t i = 0; i < num_chunks; i++) {
+
+ // Set chunk to a stringer pointing at the section of the payload that is the data for this iteration.
+ st_length_set(slice, (i + 1 < num_chunks) ? 16777098 : (st_length_get(payload) % 16777098));
+ st_data_set(slice, st_data_get(payload) + (16777098 * i));
+
+ // Process the chunk stringer into an encrypted chunk.
+ if (!(curr = encrypted_chunk_set(type, signing, keks, slice, ((i + i < num_chunks) ? 128 : 0)))) {
+ encrypted_chunk_cleanup(chunk);
+ return NULL;
+ }
+
+ if (!chunk) {
+ chunk = curr;
+ prev = curr;
+ curr = NULL;
+ }
+ else {
+ prev->next = curr;
+ prev = curr;
+ curr = NULL;
+ }
+ }
+
+ return chunk;
+}
+
+/* @brief Get the part as a decrypted data buffer.
+ *
+ * @param payload
+ * @param part
+ * @param keks
+ * @param signing
+ * @param type
+ *
+ * @return
+ */
+stringer_t * part_decrypt(stringer_t *payload, stringer_t *part, prime_chunk_keks_t *keks, ed25519_key_t *signing, uint8_t type) {
+
+ size_t part_size;
+ uint8_t curr_type;
+ uint32_t chunk_size = 0;
+ placer_t slice = pl_null();
+ stringer_t *result = NULL, *curr_chunk = NULL;
+
+ // Set the data buffer of the part stringer to the beginning of the payload.
+ st_data_set(part, st_data_get(payload));
+
+ while (true) {
+
+ // Read the chunk headers from the beginning of the remaining payload.
+ if (chunk_header_read(payload, &curr_type, &chunk_size, &slice) != 0) break;
+ part_size += st_length_get(&slice);
+
+ // TODO: Instead, check if the spanning-chunk flag (128) is set in the header.
+ // Check if the chunk is still a part of the part that we are decrypting.
+ if (curr_type != type) break;
+
+ // Pass this into encrypted_chunk_get().
+ if (!(curr_chunk = encrypted_chunk_get(signing, keks, &slice, NULL))) {
+ st_cleanup(result);
+ return NULL;
+ }
+
+ // Either append curr_chunk onto result or set result equal to chunk.
+ result = st_append(result, curr_chunk);
+
+ // Free curr_chunk.
+ st_free(curr_chunk);
+
+ // Update payload and loop if necessary.
+ st_data_set(payload, st_data_get(payload) + st_length_get(&slice));
+ st_length_set(payload, st_length_get(payload) - st_length_get(&slice));
+ }
+
+ // Construct the part-spanning chunk placer.
+ st_length_set(part, part_size);
+
+ return result;
+}
+
+// Return the binary representation of an encrypted message.
stringer_t * naked_message_get(stringer_t *message, prime_org_signet_t *org, prime_user_key_t *user) {
- placer_t chunk[7];
uint8_t type = 0;
+ placer_t chunk[7];
uint32_t size = 0;
uint16_t object = 0;
uchr_t *data = NULL;
@@ -131,7 +237,7 @@ stringer_t * naked_message_get(stringer_t *message, prime_org_signet_t *org, pri
remaining -= st_length_get(&chunk[1]);
if (chunk_header_read(PLACER(data, remaining), &type, &size, &chunk[2]) < 0 || type != PRIME_CHUNK_HEADERS ||
- !(headers = encrypted_chunk_set(keys.signing, keks, &chunk[2], NULL))) {
+ !(headers = encrypted_chunk_get(keys.signing, keks, &chunk[2], NULL))) {
ephemeral_chunk_cleanup(ephemeral);
keks_free(keks);
return NULL;
@@ -141,8 +247,10 @@ stringer_t * naked_message_get(stringer_t *message, prime_org_signet_t *org, pri
data += st_length_get(&chunk[2]);
remaining -= st_length_get(&chunk[2]);
- if (chunk_header_read(PLACER(data, remaining), &type, &size, &chunk[3]) < 0 || type != PRIME_CHUNK_BODY ||
- !(body = encrypted_chunk_set(keys.signing, keks, &chunk[3], NULL))) {
+ //(void)body_size;
+ if (//chunk_header_read(PLACER(data, remaining), &type, &size, &chunk[3]) < 0 || type != PRIME_CHUNK_BODY ||
+ !(body = part_decrypt(PLACER(data, remaining), &chunk[3], keks, keys.signing, PRIME_CHUNK_BODY))) {
+ //!(body = encrypted_chunk_get(keys.signing, keks, &chunk[3], NULL))) {
ephemeral_chunk_cleanup(ephemeral);
st_free(headers);
keks_free(keks);
@@ -150,8 +258,12 @@ stringer_t * naked_message_get(stringer_t *message, prime_org_signet_t *org, pri
}
// Tree signature.
+ // 191892
data += st_length_get(&chunk[3]);
remaining -= st_length_get(&chunk[3]);
+ // 191824
+ //data += body_size;
+ //remaining -= body_size;
if (chunk_header_read(PLACER(data, remaining), &type, &size, &chunk[4]) < 0 || type != PRIME_SIGNATURE_TREE ||
!(tree = signature_tree_alloc())) {
@@ -213,6 +325,7 @@ stringer_t * naked_message_get(stringer_t *message, prime_org_signet_t *org, pri
return result;
}
+// Return a workable struct representation of a message.
prime_message_t * naked_message_set(stringer_t *message, prime_org_key_t *destination, prime_user_signet_t *recipient) {
size_t length = 0;
@@ -273,7 +386,7 @@ prime_message_t * naked_message_set(stringer_t *message, prime_org_key_t *destin
st_cleanup(holder[0], holder[1], holder[2], holder[3], holder[4], holder[5], holder[6], holder[7], holder[8], holder[9]);
- if (!(result->metadata.common = encrypted_chunk_get(PRIME_CHUNK_COMMON, result->keys.signing, &(result->keks), common))) {
+ if (!(result->metadata.common = encrypted_chunk_set(PRIME_CHUNK_COMMON, result->keys.signing, &(result->keks), common, 0))) {
encrypted_message_free(result);
st_cleanup(common);
return NULL;
@@ -282,14 +395,18 @@ prime_message_t * naked_message_set(stringer_t *message, prime_org_key_t *destin
st_cleanup(common);
// Encrypt the headers, and the body.
- if (!(result->metadata.headers = encrypted_chunk_get(PRIME_CHUNK_HEADERS, result->keys.signing, &(result->keks), &header))) {
+ if (!(result->metadata.headers = encrypted_chunk_set(PRIME_CHUNK_HEADERS, result->keys.signing, &(result->keks), &header, 0))) {
encrypted_message_free(result);
return NULL;
}
- else if (!(result->content.body = encrypted_chunk_get(PRIME_CHUNK_BODY, result->keys.signing, &(result->keks), &body))) {
+ else if (!(result->content.body = part_encrypt(&body, PRIME_CHUNK_BODY, &(result->keks), result->keys.signing))) {
encrypted_message_free(result);
return NULL;
}
+ /*else if (!(result->content.body = encrypted_chunk_set(PRIME_CHUNK_BODY, result->keys.signing, &(result->keks), &body, 0))) {
+ encrypted_message_free(result);
+ return NULL;
+ }*/
// Generate the signatures.
if (!(tree = signature_tree_alloc())) {
diff --git a/src/providers/prime/prime.h b/src/providers/prime/prime.h
index 385ab412..ac97c4fc 100644
--- a/src/providers/prime/prime.h
+++ b/src/providers/prime/prime.h
@@ -260,7 +260,7 @@ typedef struct __attribute__ ((packed)) {
/**
* @typedef prime_encrypted_chunk_t
*/
-typedef struct __attribute__ ((packed)) {
+typedef struct __attribute__ ((packed)) prime_encrypted_chunk_t {
struct {
uint8_t type; /**< Chunk type, 1 through 255. >*/
uint32_t length; /**< Payload length, must be divisible by 16 and less than 2^24 - 1. >*/
@@ -272,9 +272,9 @@ typedef struct __attribute__ ((packed)) {
uint8_t pad;
stringer_t *data;
stringer_t *trailing;
-
stringer_t *encrypted;
prime_chunk_slots_t *slots;
+ struct prime_encrypted_chunk_t *next;
} prime_encrypted_chunk_t;
diff --git a/src/servers/imap/fetch.c b/src/servers/imap/fetch.c
index cfad6bcf..deef1568 100644
--- a/src/servers/imap/fetch.c
+++ b/src/servers/imap/fetch.c
@@ -230,8 +230,8 @@ stringer_t * imap_fetch_bodystructure(mail_mime_t *mime) {
array_t *items;
uint64_t lines = 0;
- size_t increment = 0, length;
chr_t *stream, buffer[32];
+ size_t increment = 0, length;
stringer_t *output = NULL, *current, *value, *literal, *holder[8];
if (!mime) {
@@ -260,8 +260,8 @@ stringer_t * imap_fetch_bodystructure(mail_mime_t *mime) {
while (increment < length) {
current = ar_field_st(items, increment);
- // If the current item is a literal.
+ // If the current item is a literal.
if (current && (literal = imap_build_array_isliteral(pl_init(st_char_get(current), st_length_get(current))))) {
if ((value = st_merge("sns", holder[2], holder[2] ? " " : "", literal))) {