diff options
author | Ladar Levison <ladar@lavabit.com> | 2017-06-20 07:46:14 +0300 |
---|---|---|
committer | Ladar Levison <ladar@lavabit.com> | 2017-06-20 07:46:14 +0300 |
commit | ec00019570d224896e4dc7f181b8b43fb42e6dce (patch) | |
tree | 9eee9d3c66b0e655d7b7a289e38886e1da8d44a0 | |
parent | 3b82a57bcb1b32751b256d63c8aef3c7c5963cc3 (diff) | |
parent | d19064af6b8f44a16fbf79e5ca8dff8fbe895897 (diff) |
Merge remote-tracking branch 'jpadkins/feature/spanning-chunks' into fix/networking-code-cleanup
-rw-r--r-- | check/magma/prime/prime_check.c | 96 | ||||
-rw-r--r-- | src/core/strings/length.c | 2 | ||||
-rw-r--r-- | src/providers/prime/messages/chunks/chunks.h | 4 | ||||
-rw-r--r-- | src/providers/prime/messages/chunks/encrypted.c | 25 | ||||
-rw-r--r-- | src/providers/prime/messages/messages.c | 131 | ||||
-rw-r--r-- | src/providers/prime/prime.h | 4 | ||||
-rw-r--r-- | src/servers/imap/fetch.c | 4 |
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))) { |